页面部分的介绍基本结束。有了框架之后,我们要考虑的页面中的数据通信和交互。jQuery Mobile(JQM)使用了JavaScript与框架通信以及进行内容管理的API。
1.文档事件
$(document).bind('mobileinit', function() {
// Initialization code here
});
mobileinit事件会在jQueryMobile框架载入内存之后,UI元素被渲染之前触发,可以使用它来改变一些UI全局选项。
JQM文档事件的执行顺序通常是:mobileinit - ready - load
放置位置:jQuery.js之后,jQueryMobile.js之前。
<head>
<meta charset="utf-8" />
<title>My first jQuery Mobile code</title>
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.0/jquery.mobile-1.0.min.css" />
<script src="http://code.jquery.com/jquery-1.6.4.min.js"></script>
<script>$(document).bind(<span style="background-color: rgb(51, 204, 255);">"mobileinit"</span>, function() {
// Our initialization code here
});
<script>
<script src="http://code.jquery.com/mobile/1.0/jquery.mobile-1.0.min.js"></script>
<!-- CUSTOM INITIALIZATION CODE -->
<script src="customcode.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
2.配置($.mobile代替jQuery中的$)
$.mobile.<widget_name>.prototype用于访问相应的原型。例如$.mobile.page.prototype.options可用于定义应用到每个页面实例(data-role="page")的默认属性。这些设置全局或部件默认属性的设置要放在mobileinit事件中。
2.1全局配置
用户界面配置:
$(document).bind("mobileinit", function() {
// We change default values
$.mobile.defaultPageTransition = "fade";
$.mobile.minScrollBack = 150;
$.mobile.activeBtnClass = "active-button";
});
minScrollBack默认页面最小滚动值为250像素高。
activePageClass/activeBtnClass修改当前活动页面或激活按钮的类名。
命名空间和Ajax功能:$(document).bind("mobileinit", function() {
// We change default values
$.mobile.ns = "firt";
});
为了避免框架间的冲突,可以使用ns全局属性来定义一个命名空间。例如上式使用后,页面模板就会变成:
<div data-firt-role="page">
<div data-firt-role="header" data-firt-theme="a">
</div>
<div data-firt-role="content">
</div>
</div>
如果定义了命名空间,则需要手动修改CSS文件(包括结构和主题文件)以便识别。
$.mobile.ajaxEnabled = false:禁用所有Ajax功能,所有外部页面将通过浏览器使用完整的HTTP请求加载。
默认情况下,XMLHttpRequest不支持跨域请求,但是可以通过$.mobile.allowCrossDomainPages=true来开启跨域。
本地化字符串
使用Ajax加载外部页面时显示的加载消息、外部页面无法加载时的加载错误消息以及一些其他基于组件的消息。
下面是各个消息的列表及默认值:
// Global strings
$.mobile.loadingMessage = "loading";
$.mobile.pageLoadErrorMessage = "Error Loading Page";
// 组件字符串
$.mobile.page.prototype.options.backBtnText = "Back";
$.mobile.dialog.prototype.options.closeBtnText = "Close"
$.mobile.collapsible.prototype.options.expandCueText =
" click to expand contents";
$.mobile.collapsible.prototype.options. collapseCueText = " click to collapse contents";
$.mobile.listview.prototype.options.filterPlaceholder = "Filter items...";
$.mobile.selectmenu.prototype.options.closeText = "Close";
创建一个类似的中文版本的JQM文本方案:
$(document).bind('mobileinit', function() {
// Global strings
$.mobile.loadingMessage = "正在加载";
$.mobile.pageLoadErrorMessage = "加载页面出错";
// Widget strings
$.mobile.page.prototype.options.backBtnText = "后退";
$.mobile.dialog.prototype.options.closeBtnText = "关闭"
$.mobile.collapsible.prototype.options.expandCueText = "点击展开";
$.mobile.collapsible.prototype.options. collapseCueText = " 点击收起 ";
$.mobile.listview.prototype.options.filterPlaceholder = " 过滤 ";
$.mobile.selectmenu.prototype.options.closeText = " 关闭 ";
});
改变页面默认主题:
$(document).bind('mobileinit', function() {
$.mobile.page.prototype.options.addBackBtn = true;
$.mobile.page.prototype.options.backBtnTheme = "e";
$.mobile.page.prototype.options.headerTheme = "b";
$.mobile.page.prototype.options.footerTheme = "d";
});
2.3部件配置
JQM中的每个部件widget都有自己的默认配置属性,可以通过部件的prototype属性中的options对象来改变部件的默认配置,接口为$.mobile.<部件名>.prototype.options
$(document).bind('mobileinit', function() {
// 在所有listviews中启用过滤
$.mobile.listview.prototype.filter = true;
// 在所有选择框上启用非原生菜单
$.mobile.selectmenu.prototype.nativeMenu=false;
});
<strong>
</strong>
<strong>3.实用工具</strong>
3.1Data-*工具
取得页面上所有btn集合:
var buttons = $("a[data-role=button"]);
JQM添加了一个名为jqmData的过滤器,并会应用我们指定的命名空间,上面的代码可以更改为:
<pre name="code" class="html">var buttons = $("a:jqmData(role='button')");
同时,在JQM集合对象上应该使用jqmData和jqmRemoveData来代替原来的jQuery函数data和removedata,例如:
$("a").jqmRemoveData("transition");
$("#button1").jqmData("theme", "a");
3.2页面工具
当前页面:
var currentPageId = $.mobile.activePage.id;
可以通过$.mobile.pageContainer属性访问当前页面的容器(通常为body元素),框架中最有用的工具是$.mobile.changePage方法,它允许我们转向另一个页面,就像用户点击了相应的链接一样。
加载外部页面:
$.mobile.changePage("external.html");
转向当前文档中已经存在的内部页面:
$.mobile.changePage($("#pageId"));
$.mobile.changePage($("#page2"), {
transition: "slide",
reverse: true
});
示例:通过POST方式发送数据并加载一个外部页面:
<script>
function viewProduct(idProduct) {
$.mobile.changePage("productdetail.php", {
method: "post",
data: {
action: 'getProduct',
id: idProduct
},
transition: "fade"
});
}
</script>
<!-- ... -->
<a href="javascript:viewProduct(5200)" data-role="button">Product details</a>
3.3平台、路径、UI工具
$.mobile对象中用于查询当前平台的工具。
getDocumentUrl():返回原始文档的RU
$.mobile.path访问路径管理工具。
parseUrl(url):返回一个对象,各个属性对应该URL的各个部分
makePathAbsolute(relativePath,absolutePate):基于相对路径返回绝对路径
makeURLAbsolute(relativeUrl,absoluteUrl):基于相对URL返回绝对URL
isSameDomain(Url1,Url2):如果两个URL同域名则返回true
isRelativeUrl(Url):如果URL是相对地址则返回true
isAbsolute(Url):如果URL是绝对地址则返回true
$.mobile.silentScroll(y)可以将页面滚动到任意位置,同时不显示动画,也不触发任何时间。
// 显示加载信息,并在2s后将其隐藏
$.mobile.showPageLoadingMsg();
setTimeout(function() {
$.mobile.hidePageLoadingMsg();
}, 2000);
$.mobile.fixedToolbars.show()/.hide():显示、隐藏固定工具栏
4.自定义过渡
添加一个explode过渡类型:
$.mobile.transitionHandlers.explode = explodeTransitionHandler;
修改默认的过渡,将它赋值为任何其他处理函数
$.mobile.defaultTransitionHandler = explodeTransitionHandler;
</pre><pre name="code" class="html">过渡处理函数是一个JavaScript函数,接受四个参数:过渡名,reverse(如果设置为true,表示本过渡将反转调用),toPage(指向目标页面的jQuery DOM对象),fromPage(指向原始页面的jQuery DOM对象)
5.动态内容:
5.1创建页面:
<div data-role="page">
<div data-role="header">
<h1>Dynamic page</h1>
</div>
<div data-role="content">
<a id="button1" href="javascript:addPages()" data-role="button">Add Pages</a>
<ul id="list1">
</ul>
</div>
</div>
function addPages() {
for (var i=1; i<5; i++) {
var page = $("<div>").jqmData("role", "page").attr("id", "page" + i);
// header
$("<div>").attr("data-role", "header").append($("<h1>")
.html("Page " + i)).appendTo(page);
// content
$("<div>").attr("data-role", "content").append($("<p>")
.html("Contents for page " + i))
.appendTo(page);
$("body").append(page);
$("<li>").append($("<a>").attr("href", "#page"+i).html("Go to page " + i))
.appendTo("#list1");
}
$("#button1").hide();
};
动态创建页面有一个缺点:如果用户在某个新建的页面上刷新当前页面,必须监听mobileinit并检查(通过读取页面地址中的散列值或某个页面事件)用户是否正在加载某个动态页面,否则无法刷新。第二次加载时,动态页面将不存在,需要重新创建。
创建动态页面的最佳方法是只连接它们,例如:连到#page1并捕获pagebeforechange事件,修改框架对应的行为。
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8" />
<title>jQuery Mobile</title>
<script src="jquery.js"></script>
<link rel="stylesheet" type="text/css" href="jquery.mobile-1.0.css">
<script src="jquery.mobile-1.0.js"></script>
<script>
$(document).bind('pagebeforechange', function(event, data) {
// 从data.toPage中收到目标页面,将它标准化
var url = $.mobile.path.parseUrl(data.toPage).hash;
if (url!=undefined && url.length>5 && url.substring(0, 5)=="#page") {
// We dynamically inject a new page
var id = url.substring(5);
// 使用DOM中已经存在的页面模板
$("#pageTemplate h1").html("Page " + id);
//转向真实的页面模板,同时不在访问历史上使用的真实页面
$.mobile.changePage($("#pageTemplate"), {dataUrl: data.toPage});
// 阻止正常页面过渡
event.preventDefault();
}
});
</script>
<meta name="viewport" content="width=device-width,user-scalable=no">
</head>
<body>
<div data-role="page">
<div data-role="header">
<h1>Dynamic pages</h1>
</div>
<div data-role="content">
<a id="button1" href="#page1" data-role="button">Page 1</a>
<a id="button1" href="#page2" data-role="button">Page 2</a>
<a id="button1" href="#page3" data-role="button">Page 3</a>
<a id="button1" href="#page4" data-role="button">Page 4</a>
</div>
</div>
<div data-role="page" id="pageTemplate">
<div data-role="header">
<h1>Header</h1>
</div>
<div data-role="content">Content</div>
<div data-role="footer">
<h4>Footer</h4>
</div>
</div>
</body>
</html>
5.2创建部件
动态创建部件需要调用部件对应的构造器。每个部件都有自己的构造器,它们就是与部件名同名的jQuery函数,例如执行$("#list1").listview(),则该ul将马上被转换并渲染为一个列表视图。
将a元素转换为按钮:
$("a").button();
//或
var button = $("<a>").attr("href", "somewhere.html").button();
5.3更新部件
动态添加内容后,需要刷新这个部件。
$("#list1").listview('refresh');
$("#checkbox").val('true').checkboxradio('refresh');
用于创建CSS网格。
$("#element").grid();
根据它的子元素的数目,框架将自动为该元素应用正确的ui-grid-<letter>类,为其子元素应用ui-block-<letter>类。
</pre><pre name="code" class="html">
7.改变页面内容
要刷新一个容器,只需要在页面上触发create事件,这时每个部件就会再次检查是否需要创建新的实例。
$("#content").html(newHTMLcontentWithWidgets);
$("#page1").trigger("create");
通常每个部件的构造器都会响应页面的create事件,以便检查是否需要创建对应的控件。
8.处理事件
8.1页面事件
要全局处理页面事件,可以调用$(document).bind,也可以调用更明确的$(":jqmData(role='page')").bind。
创建事件:
pagebeforecreate:页面已插入DOM,但是组件还未创建
pagecreate:页面已被创建,但组件还未渲染
pageinit:页面已完全加载
pageremove:页面已从DOM移除
$("#page2").live("pageinit", function(event) {
});
pagebeforeload:在所有Ajax请求完成之前执行
pageload:当新页面已被加载并插入到DOM后执行
pageloadfailed:指定页面无法加载时执行
这些事件处理程序都会受到两个参数,一个事件对象和一个数据对象。
$(document).bind("pageloadfailed", function(event, data) {
data.preventDefault();//阻止默认行为
// Custom error management
});
pagebeforechange:在页面改变发生之前以及过渡开始之前执行
pagechange:在页面改变完成之后执行
pagechangefailed:页面改变无法完成时执行
toPage:如果目标页面是外部页面,则值为目标页面的URL字符串;如果是内部页面,则值为目标页面的DOM对象
options:与发送到$.mobile.changePage的选项相同
pagebeforeshow:在过渡并显示页面之前执行(页面仍然处于隐藏状态)
pageshow:在页面已完成加载过渡并正显示在屏幕上时执行
pagebeforehide:在页面隐藏之前执行
pagehide:页面已完成卸载过渡并已隐藏时执行
8.2方向事件
$(document).bind("orientationchange", function(orientation) {
if (orientation=="landscape") {
// 现在是纵向
} else {
// 现在是横向
}
});
8.4手势事件
tap:在屏幕上快速触摸一下时触发
taphold:触摸屏幕并持续按住1s时触发
swipeleft:从右划到左时触发
swiperight:从左划到右时触发
$(document).bind("mobileinit", function() {
$("#page2").live("swiperight", goBackToPage1);
});
function goBackToPage1() {
$.mobile.changePage("#page1", { reverse: true });
$("#page2").unbind("swiperight", goBackToPage1);
}