深入jQuery Mobile
jQueryMobile上手非常容易,但是要做到近似于原生APP的效果则很不容易。 以下内容不断更新中,均为实际开发中的经验
追信魔盒PhoneGap打包模式下的最佳模式
追信魔盒的PhoneGap打包模式,将所有HTML文件、CSS文件和JS文件打包在客户端中,这样就不考虑在线模式的网络延迟问题,可以用各种方式将应用的表现更贴近原生程序
- 采用OPOA(One Page, One Application)模式,将所有主要内容放置在一张页面中,这样可以确保不同的Page切换最为顺畅。
- 尽可能将所有的点击链接通过javascript来控制。绑定jQueryMobile的tap事件来处理。这样可以确保最快响应点击事件
- 使用$(document).bind('pageinit'),而不是 $(document).ready()。
- 对不同的Page中的JS脚本分别实现载入后运行(默认的教程都是教你使用$(document).bind('pageinit')。例如:
$("#Home").live('pageinit',function() {
//在这里执行#Home页面加载后需要运行的方法
});
- 尽可能避免在转场时使用fade,这个方法在很多场合容易闪屏,使用slide相对保险一些。
- 避免使用alert来弹出提醒,可以考虑使用PhoneGap的通知事件来实现纯原生客户端的提醒样式
固定顶部导航栏以及可能引发的问题
对于顶部导航栏,我们通常使用data-position="fixed"来固定顶部的显示。
如图,顶部固定的代码:
<div data-role="header" data-position="fixed">
<a href="#Home" data-icon="back" data-direction="reverse" data-transition="slide" >返回</a>
<h1>
复合大城
</h1>
<a href="#Home" data-icon="home" data-iconpos="notext" data-direction="reverse" data-transition="slide" class="ui-btn-right">首页</a>
<div class="segmented-control ui-bar-d">
<div data-role="controlgroup" data-type="horizontal" id="fhdcList">
<a href="#" class="ui-btn-active" data-role="button">非凡血统</a>
<a href="#" data-role="button" >完美规划</a>
<a href="#" data-role="button" >大城崛起</a>
<a href="#" data-role="button" >商学院</a>
</div>
</div>
</div>
这样的效果在表现上已接近原生效果。
但是如果在真机打包模式下(并且所有Page放在一个Html文件中),会发现如果前后两张页面都采用了固定头部,在Slide过场效果下,第一次切换会先只显示下一张Page的头部覆盖当前Page,再切换到下一张,而并非第二张Page完整显示。 为了避免这种情况,可以将第一张Page的头部的fix属性去掉。对于一般的软件,如果只有两层内容深度,那么只要首页的顶部不固定即可。(对于此问题尝试增加DOM缓存等都无效,仅测试出这个解决方案)
点击链接响应速度慢的问题
对于a标记的点击导航,默认是在onclick事件中处理的。而移动客户端对onclick的响应相比PC浏览器有着明显的几百毫秒延迟。
在移动浏览器中对触摸事件的响应顺序应当是: ontouchstart -> ontouchmove -> ontouchend -> onclick
因此,如果确实要加快对点击事件的响应,就应当绑定ontouchend事件。
如果不用jQueryMobile,可以考虑用第三方的脚本,例如 http://cubiq.org/remove-onclick-delay-on-webkit-for-iphone 。而那个地址中的代码不支持Android,可以考虑采用评论中的代码。这个脚本主要考虑到ontouchstart和ontouchend的触摸点位移,确保不会在用户滑动(swipe)画面后触发到点击事件。
对于使用jQueryMobile的人来说就幸运很多了,使用内置的tap事件即可在ontouchend事件环节捕获到被点击的请求,这个方法的响应时间明显快于onclick事件。代码范例如下:
$("#fhdclink").live('tap',function(event) {
$.mobile.changePage($("#fhdc"), {
transition: 'slide',
reverse: false
} );
return false;
});
对载入文字和错误文字的汉化
$(document).bind("mobileinit",function() {
$.mobile.loadingMessage = '页面载入中';
$.mobile.pageLoadErrorMessage = '页面载入失败';
});
整合PhoneGap(Cordova)
<script data-minified="true" src="js/jquery.min.js"></script>
<script type="text/javascript" charset="utf-8" src="js/cordova.js"></script>
<script type="text/javascript" charset="utf-8">
$(document).bind("mobileinit",function() {
$.support.cors = true;
$.mobile.allowCrossDomainPages=true;
});
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
// Register the event listener
document.addEventListener("backbutton", onBackKeyDown, false);
}
function onBackKeyDown() {
history.back();
return false;
}
</script>
<script data-minified="true" src="js/jquery.mobile-1.1.0.min.js"></script>
手机环境下jQuery的DOM性能问题
使用jQuery的选择器,在PC环境下效果比较理想,但在手机环境下DOM选择会比较卡,如果选择器使用频繁,会造成用户UI响应变化滞后。 jQuery默认不会缓存DOM选择,每次使用选择器都会从根节点进行检索,因此,强烈建议缓存DOM选择结果。
例如标签页效果,未优化前:
$("#fhdcList a").each(function(index){
$(this).click(function(){
$("#fhdcList a.ui-btn-active").removeClass("ui-btn-active");
$("#fhdcList a:eq(" + index + ")").addClass("ui-btn-active");
$(".fhdcTab:visible").hide();
$(".fhdcTab:eq(" + index + ")").show();
});
});
这样在循环时每一句语句都会对DOM树从头到尾查找一遍。在PC环境下看不出时延,但在手机环境下切换时明显有点卡。这需要优化:
var tab = $(".fhdcTab");
var listdiv = $("#fhdcList");
listdiv.find("a").each(function(index){
$(this).live('tap',function(event) {
listdiv.find("a.ui-btn-active").removeClass("ui-btn-active");
tab.hide();
tab.eq(index).show();
listdiv.find("a:eq(" + index + ")").addClass("ui-btn-active");
});
});