jQuery Mobile页面返回不需要重新get


Posted in Javascript onApril 26, 2016

jQuery Mobile 是用于创建移动 Web 应用的前端开发框架。

jQuery Mobile 可以应用于智能手机与平板电脑。

jQuery Mobile 使用 HTML5 & CSS3 最小的脚本来布局网页。

最近公司的web app项目,使得我有幸一直接触和学习jQuery Mobile。这确实是一个很不错的移动开发库,有助于擅长web开发的工程师,快速入门并构建自己的移动应用。但是在前两天,我碰到了一个问题,使我查了很多资料都没有找到很好的解决方案,最终只能逼着我读jQuery Mobile的源码,再写了个扩展,才得以解决。下面请让我娓娓道来。

问题描述

假设在项目中,有三个页面,分别是main.html、test1.html、test2.html(后面分别简称main、test1、test2),其中main页面是包含一个转向到test1页面的链接(即a标签),test1中有一个属性为data-rel=”back”的链接和一个转向到test2的链接,test2只有一个属性为data-rel=”back”的链接。main转向到test1后,点击back链接返回main(相当于点击浏览器的返回按钮),无需重新发送get请求;但是当test1转向到test2,在test2页面点击back链接想返回test1时,会重新发送一个get请求。这样导致的问题就是:test1做的所有操作,在test2返回后,都会失效。比如A是一个分页的列表页面,翻到第二页后转向到B,那么当返回A后,就无法地位到第二页。

原因分析

我首先用firebug看了一下html的结构,发现jQuery Mobile会把main和test1加入到页面结构中去,当从test1转向到test2后,test1会被自动删除,这样dom树中,只包含了main和test2,所以在test2返回test1就会在发送一个get请求。那么是不是意味着,只要能把历史页面缓存到dom中(就像main和test1一样),就可以解决这个问题。

解决问题

经过一番查找,在jQuery Mobile官网看到一段《Caching pages in the DOM》的描述:

Caching pages in the DOM
To keep all previously-visited pages in the DOM, set the domCache option on the page plugin to true, like this:
$.mobile.page.prototype.options.domCache = true;
Alternatively, to cache just a particular page, you can add the data-dom-cache="true" attribute to the page's container:
<div data-role="page" id="cacheMe" data-dom-cache="true">
You can also cache a page programmatically like this:
pageContainerElement.page({ domCache: true });
The drawback of DOM caching is that the DOM can get very large, resulting in slowdowns and memory issues on some devices. If you enable DOM caching, take care to manage the DOM yourself and test thoroughly on a range of devices.

从这段引文中应该可以看到,这三种方法都可以缓存页面到dom中,于是我就使用了第二种方法,即在page的div上增加了data-dom-cache=”true”属性,但是却出现了以下两个问题:

1、如下图所示,当我的访问路径是main->test1->test2->test1(test2是history.back()返回的)时,用firebug可以看到,test2仍然存在于dom中,这样的结果就如红色部分描述的:DOM会变得很大,结果会使页面变慢和一些设备上的内存错误。

jQuery Mobile页面返回不需要重新get

2、当我存在这样一个页面,它通过不同的参数显示不同的内容,并且页面上,有一段js脚本,会对页面上的元素做些处理,而我们常用的方式就是用id来获得目标元素,由于我们是用了cache缓存page,就会导致js事件或者操作混乱。比如在这里我增加了一个test1_1页面,它的内容几乎和test1一样,他们都有相同id的div和相同事件处理的button,这个事件做的事情就是往这个div中增加内容,当访问路径为main->test1->test1_1,在test1_1上点击按钮,会发现好像没有触发这个事件,其实它已经触发了,只是内容增加到test1中的div中了,分别入下图

jQuery Mobile页面返回不需要重新get

jQuery Mobile页面返回不需要重新get

所以对于目前大多数应用,这个方案是不可取的,除非自己管理dom中页面的生命周期。

优化方案

通过上面的实验,我也知道了需要满足我的需求,就只能自己管理dom中页面的生命周期了。那么就涉及到一个问题:页面什么时候过期(即从dom中删除)呢?根据我的需求,当从test2返回到test1时,就应该从dom中删除test2,同理从test1返回main时,从dom中删除test1。如果再次从main导航到test1,就得发起一个get请求,我认为这是合理的,因为用户不会认为点击链接到新页面还需要缓存。所以我应该在页面显示前或者显示后,删除它之后的history,于是我就在pagebeforeshow、pageshow的时候做了删除操作,即如下脚本(插件形式):

(function($, undefined) {
$.fn.subpage = function(options) {
$(document).bind(
"pagebeforeshow",
function() {
var forword = $.mobile.urlHistory.getNext();
if (forword) {
var dataUrl = forword.url;
var forwordPage=$.mobile.pageContainer
.children(":jqmData(url='" + dataUrl + "')");
if(forwordPage){
forwordPage.remove();
}
}
$.mobile.urlHistory.clearForward();
});
};
$(document).bind("pagecreate create", function(e) {
$(":jqmData(role='page')", e.target).subpage();
});
})(jQuery);

结果事与愿违,在页面返回时,出现了js脚本错误,如下图:

jQuery Mobile页面返回不需要重新get

那么是什么原因呢?不在这个事件里做处理,那在哪里处理呢?于是我仔细研读了一下jQuery Mobile源码,发现了下面一段:

transitionPages( toPage, fromPage, settings.transition, settings.reverse )
.done(function() {
removeActiveLinkClass();
//if there's a duplicateCachedPage, remove it from the DOM now that it's hidden
if ( settings.duplicateCachedPage ) {
settings.duplicateCachedPage.remove();
}
//remove initial build class (only present on first pageshow)
$html.removeClass( "ui-mobile-rendering" );
releasePageTransitionLock();
// Let listeners know we're all done changing the current page.
mpc.trigger( "pagechange", triggerData );
});

页面在切换完后,会触发pagechange事件,于是我把pagebeforeshow改成了pagechange,一切都按预期运行,并且没有错误,终于大功告成了。

总结

在使用该插件时,请注意以下几点:

1、必须在引用该脚本之前,引用jquery和jquery mobile脚本文件;

2、必须在page上增加data-dom-cache="true"。

以上所述是小编给大家介绍的jQuery Mobile页面返回不需要重新get 的相关说明,希望对大家有所帮助!

Javascript 相关文章推荐
可编辑下拉框的2种实现方式
Jun 13 Javascript
javascript setinterval 的正确语法如何书写
Jun 17 Javascript
jQuery实现拖动调整表格单元格大小的代码实例
Jan 13 Javascript
全面解析Bootstrap表单使用方法(表单控件)
Nov 24 Javascript
浅谈js中对象的使用
Aug 11 Javascript
jQuery Easyui使用(二)之可折叠面板动态加载无效果的解决方法
Aug 17 Javascript
React Native中的RefreshContorl下拉刷新使用
Oct 09 Javascript
微信小程序自定义tabBar组件开发详解
Sep 24 Javascript
微信小程序实现树莓派(raspberry pi)小车控制
Feb 12 Javascript
JS数组降维的实现Array.prototype.concat.apply([], arr)
Apr 28 Javascript
JavaScript中的几种继承方法示例
Dec 06 Javascript
ES6的循环与可迭代对象示例详解
Jan 31 Javascript
jQuery 中的 DOM 操作
Apr 26 #Javascript
Bootstrap每天必学之弹出框(Popover)插件
Apr 25 #Javascript
基于JS实现EOS隐藏错误提示层代码
Apr 25 #Javascript
Bootstrap每天必学之按钮(Button)插件
Apr 25 #Javascript
第一章之初识Bootstrap
Apr 25 #Javascript
第二章之Bootstrap 页面排版样式
Apr 25 #Javascript
第三章之Bootstrap 表格与按钮功能
Apr 25 #Javascript
You might like
php基于单例模式封装mysql类完整实例
2016/10/18 PHP
PHP使用星号替代用户名手机和邮箱的实现代码
2018/02/07 PHP
始终在屏幕中间显示Div的代码(css+js)
2011/03/10 Javascript
一个关于jqGrid使用的小例子(行按钮)
2011/11/04 Javascript
JSON 数字排序多字段排序介绍
2013/09/18 Javascript
JavaScript显示当然日期和时间即年月日星期和时间
2013/10/29 Javascript
js确认删除对话框效果的示例代码
2014/02/20 Javascript
基于Arcgis for javascript实现百度地图ABCD marker的效果
2015/09/12 Javascript
jQuery包裹节点用法完整示例
2016/09/13 Javascript
javascript中闭包概念与用法深入理解
2016/12/15 Javascript
基于vue+ bootstrap实现图片上传图片展示功能
2017/05/17 Javascript
Vue组件模板形式实现对象数组数据循环为树形结构(实例代码)
2017/07/31 Javascript
基于JavaScript实现淘宝商品广告效果
2017/08/10 Javascript
JavaScript中错误正确处理方式小结你用对了吗
2017/10/10 Javascript
AngularJS模糊查询功能实现代码(过滤内容下拉菜单排序过滤敏感字符验证判断后添加表格信息)
2017/10/24 Javascript
vue 监听某个div垂直滚动条下拉到底部的方法
2018/09/15 Javascript
Vant的安装和配合引入Vue.js项目里的方法步骤
2018/12/05 Javascript
微信小程序顶部导航栏滑动tab效果
2019/01/28 Javascript
详解VUE调用本地json的使用方法
2019/05/15 Javascript
layui radio点击事件实现input显示和隐藏的例子
2019/09/02 Javascript
基于Vue+Webpack拆分路由文件实现管理
2020/11/16 Javascript
[12:29]2018国际邀请赛 开幕秀
2018/08/22 DOTA
python中列表元素连接方法join用法实例
2015/04/07 Python
详解Python中break语句的用法
2015/05/14 Python
Python3处理文件中每个词的方法
2015/05/22 Python
Python WXPY实现微信监控报警功能的代码
2017/10/20 Python
Python3简单实例计算同花的概率代码
2017/12/06 Python
python基于http下载视频或音频
2018/06/20 Python
为什么是 Python -m
2020/06/19 Python
extern在函数声明中是什么意思
2014/01/19 面试题
化验室技术员岗位职责
2013/12/24 职场文书
美食节目策划方案
2014/05/31 职场文书
领导个人查摆剖析材料
2014/10/29 职场文书
财产保全担保书
2015/01/20 职场文书
个人简历求职信范文
2015/03/20 职场文书
评测 | 大屏显示带收音机的高端音箱,JBL TUNE2便携式插卡音箱实测
2021/04/24 无线电