jQuery Mobile页面返回无需重新get

最近公司的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会变得很大,结果会使页面变慢和一些设备上的内存错误。

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

所以对于目前大多数应用,这个方案是不可取的,除非自己管理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源码,发现了下面一段:

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"。

时间: 2024-08-10 15:05:12

jQuery Mobile页面返回无需重新get的相关文章

02.Jquery Mobile介绍以及Jquery Mobile页面与对话框

一.为什么要学Jquery Mobile   JqueryMobile 是jquery的移动版本,懂基本的jquery知识,会简单的html+css就可以完成很多复杂的功能,还有就是这个框架在企业中用的也是比较多的   二.Adobe Dreamweaver CS6 环境搭建以及软件破解   软件安装步骤:   http://www.phonegap100.com/article-79-1.html            软件下载链接地址:   http://bbs.phonegap100.co

(二)Jquery Mobile介绍以及Jquery Mobile页面与对话框

Jquery Mobile介绍以及Jquery Mobile页面与对话框  一. Adobe Dreamweaver CS6 环境 最新版本的cs6会支持JM的使用,有自动提示功能,很强大.安装说明地址:http://www.phonegap100.com/article-79-1.html 下载地址说明:http://bbs.phonegap100.com/thread-135-1-1.html  二.JM说明 默认data-ajax="true"jquery mobile 是默认通

使用 jQuery Mobile 与 HTML5 开发 Web App —— jQuery Mobile 页面事件与 deferred

在系列的上一篇文章<使用 jQuery Mobile 与 HTML5 开发 Web App —— jQuery Mobile 事件详解>中,Kayo 介绍了除页面事件外的其他 jQuery Mobile 事件,而页面事件由于事件数较多,并且涉及 jQuery 中一个比较复杂的对象 deferred ,因此在本文中单独说明.jQuery Mobile 页面事件使用分为页面加载事件 (Page load events),页面跳转事件 (Page change events),页面显示/隐藏事件 (

用谷歌浏览器Chrome浏览jQuery Mobile页面需要配置Tomcat服务器

在浏览jQuery Mobile 页面中,除了 Chrome浏览器出错外,其他的浏览器都ok: 这里,是因为需要单独配置 Tomcat 服务: 1.先配置java jdk: 2.下载,安装,配置,Tomcat 服务器(直接去官网下载 zip 版本就OK,然后\bin文件夹下,可以找到startup.bat文件) 配置: 在环境变量中,添加 变量名:CATALINA_HOME 变量值:刚刚安装的路径(或者解压后的路径......apache-tomcat-8.0.28\)就ok了: 配置好后,然后

jQuery Mobile 页面事件

jQuery Mobile 页面事件 在 jQuery Mobile 中与页面打交道的事件被分为四类: Page Initialization - 在页面创建前,当页面创建时,以及在页面初始化之后 Page Load/Unload - 当外部页面加载时.卸载时或遭遇失败时 Page Transition - 在页面过渡之前和之后 Page Change - 当页面被更改,或遭遇失败时 jQuery Mobile Initialization 事件 当 jQuery Mobile 中的一张典型页面

(01)创建第一个jQuery Mobile页面

jQuery Mobile 是一个适配pc端和移动端的前台开放框架,当然很多时候主要用于移动端的开发.怎样搭建一个jQuery Mobile的开发环境呢?其实很简单,我们只需要引入的css.js和images等资源文件即可. 引入这些资源文件有两个方法: 1.从 CDN 中引入 jQuery Mobile 这个方法比较简单,你只需要引入css和js文件即可,不需要引入images文件,它们都已经存放在cdn服务器上了,当然这样不好的地方就是你不可以修改图片或者是js和css文件了. <!--jQ

关于jquery mobile 页面闪烁与抖动问题

1.闪烁:在用a链接跳转到另一个页面的时候,页面总会抖动几下,其实就是页面切换时的transition特效,jqm貌似默认了这项. 解决方案:在a链接添加transition:none; 属性就可以啦. 2.抖动:同样的,也是在a链接跳转时出现的一种情况,原因即是jqm的a链接默认是用ajax进行跳转了,造成了css变形问题,需要刷新才能解决. 解决方案:在a链接添加rel="external"; 属性就可以啦. 关于jquery mobile 页面闪烁与抖动问题

[ Talk is Cheap Show me the CODE ] : jQuery Mobile页面布

[ Talk is Cheap Show me the CODE ] : jQuery Mobile页面布局 当我们专注地研究人类生活的空虚,并考虑荣华富贵空幻无常时,也许我们正在阿谀逢迎自己懒惰的天性. Written In The Font 为了app的手机端,我选择了 jQuery Mobile  ,学习中出一系列的博客吧.我喜欢的一句话 "Talk is Cheap Show me the CODE",所以过多的废话 jjyy 我不太会,我直接上代码上样式.想玩手机端的可以来看

JQuery Mobile 页面参数传递(转)

在单页模版中使用基于HTTP的方式通过POST和GET请求传递参数,而在多页模版中不需要与服务器进行通信,通常在多页模版中有以下三种方法来实现页面间的参数传递. 1.GET方式:在前一个页面生成参数并传入下一个页面,然后在下一个页面中进行GET内容解析. 2.通过HTML5的Web Storage进行参数传递. 3.建立当前页面变量,在前一个页面将所需传递的参数内容赋值到变量中,在后一个页面从变量中将参数取出来.(程序灵活性较弱) 一.以GET方式实现页面间参数传递 01.<!DOCTYPE h