`
wmhcymx
  • 浏览: 21159 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

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

dom_cache

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

dom_cache_test1_1

dom_cache_test1

所以对于目前大多数应用,这个方案是不可取的,除非自己管理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.subpage

那么是什么原因呢?不在这个事件里做处理,那在哪里处理呢?于是我仔细研读了一下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

    首先,本文的核心内容是关于jQuery Mobile框架下,页面在返回时无需重新进行get请求的方法。jQuery Mobile是一个基于HTML5和CSS3的前端开发框架,特别设计用于开发移动Web应用。在使用jQuery Mobile开发webapp项目时...

    JQueryMobile与后台通信

    3. **$.getJSON()和$.get(),$.post()**:针对JSON数据的GET请求,可以使用$.getJSON();而$.get()和$.post()则是简化版的GET和POST请求。 **二、Page Events:处理页面生命周期** 1. **页面生命周期**:jQuery ...

    jquery mobile 滚动加载内容

    当我们谈论“jQuery Mobile 滚动加载内容”时,我们实际上是在讨论一种动态加载技术,即在用户滚动页面到接近底部时,通过 AJAX(异步 JavaScript 和 XML)技术从服务器获取并插入更多内容,以实现无尽滚动的效果。...

    jquery mobile web api开发例子

    在C#中,创建一个Web API2控制器,处理GET请求并返回JSON数据。 ```csharp using System.Web.Http; using Newtonsoft.Json; public class YourEndpointController : ApiController { [HttpGet] public ...

    jQuery mobile带历史记录的仿谷歌搜索

    总之,“jQuery mobile带历史记录的仿谷歌搜索”是一个结合了jQuery Mobile的页面结构、事件处理、AJAX请求、历史管理和本地存储等多个技术点的项目。通过实践这个项目,开发者不仅能提升jQuery Mobile的使用技能,...

    jquerymobile滚动加载内容

    在jQuery Mobile中,可以监听页面的`scrollstart`和`scrollstop`事件来实现滚动加载内容的功能。`scrollstart`事件在用户开始滚动时触发,而`scrollstop`事件在用户停止滚动后触发。我们可以结合这两个事件来决定...

    jQuery mobile要联网的地图技术

    在jQuery Mobile中,可以使用`$.ajax()`或`$.getJSON()`方法来异步加载地图数据。例如,我们可以从服务器获取用户的当前位置,然后使用这个信息在地图上定位。 在文件"subwayMap_Plugin_0.5.0"中,可能包含了一个...

    jquerymobile实现火车列次查询

    《使用jQuery Mobile实现火车列次查询系统》 在网页开发中,jQuery Mobile是一个强大的框架,专为移动设备设计,提供了一套完整的用户界面组件和交互效果。本教程将深入探讨如何利用jQuery Mobile来构建一个实用的...

    jquery mobile web api 带下拉,上拉滑动分页滚动示例

    jQuery Mobile的核心是其页面结构和数据绑定机制。页面通常由一系列独立的“页面”元素组成,每个元素都可以通过AJAX加载或初始HTML文档中包含。页面间的导航可以通过链接和表单实现,这些链接和表单被jQuery Mobile...

    jquerymobile小例子

    这个“jquerymobile小例子”是针对手机端开发的一个实践项目,结合了服务端的 EasyUI 和 Java Servlet 技术,数据存储则采用 MySQL 数据库。 1. **jQuery Mobile 基础** - **页面结构**:jQuery Mobile 需要特定的...

    jqueryMobile省市二级菜单联动

    这通常涉及到发送 GET 请求到服务器端的接口,并处理返回的 JSON 数据。 5. **CSS 自定义** 虽然 jQuery Mobile 提供了默认的主题,但有时可能需要自定义样式以满足特定的设计需求。可以通过修改或扩展框架的 CSS ...

    jquerymobile实现拖动分页加载页面功

    jQuery Mobile,作为一个流行的前端框架,为开发者提供了丰富的功能,包括拖动分页加载页面的功能。本文将深入探讨如何利用jQuery Mobile实现这一特性。 首先,jQuery Mobile的核心在于其触摸友好的界面和数据绑定...

    jQueryMobile雅虎新闻

    该脚本接收客户端请求后,再向雅虎新闻RSS源发起HTTP GET请求,并将结果返回给客户端。 ##### jQuery Mobile页面结构 在jQuery Mobile框架中,页面结构通常由一个父页面及其包含的多个子页面组成。子页面之间通过...

    Jquery整理+JqueryMobile文檔

    5. **Ajax交互**: jQuery的`.ajax()`方法是进行异步数据交互的核心,支持GET和POST请求,可以处理JSON、XML等多种数据格式。`.load()`, `.get()`, `.post()`等简化版的API也提供了更便捷的使用方式。 6. **插件生态...

    jquery mobile html5下拉刷新

    5. **更新页面内容**:在AJAX请求成功后,解析返回的数据,并将其插入到页面的相应位置,或者替换现有内容。 6. **动画反馈**:为了提供更好的用户体验,可以添加一些动画效果,如加载指示器,表明数据正在加载。当...

    手机页面内容逐渐加载jquery.mobile插件

    在移动互联网领域,优化用户体验是至关重要的,而“手机页面内容逐渐加载jquery.mobile插件”正是为此目的设计的。这个插件充分利用了jQuery Mobile的功能,实现了网页内容的渐进式加载,即用户在滚动页面时,内容会...

    【叨、校长】PhoneGap+jQuery Mobile+Rest 访问远程数据

    c) 编写JavaScript代码,使用$.ajax()或$.getJSON()发送GET请求获取数据。 d) 在接收到响应后,解析JSON数据并更新jQuery Mobile的页面元素。 e) 如果需要更新或删除数据,使用POST、PUT或DELETE方法发送相应请求...

    jquerymobile isscroll 实现上拉加载下拉刷新

    对于jQuery,可以使用`$.ajax`或`$.getJSON`方法,并设置`dataType: 'jsonp'`来实现JSONP请求。 例如,使用JSONP请求: ```javascript function loadMoreData(callback) { $.ajax({ url: '...

    Jquery Mobile

    **jQuery Mobile:上拉刷新与下拉加载更多** jQuery Mobile 是一个轻量级、触屏优化的 JavaScript 框架,专为移动设备设计。它提供了丰富的组件和接口,简化了移动 Web 应用程序的开发。在描述中提到的“上拉刷新”...

    jquery-1.7.1 及 jquery1.4.1中文手册(最新)

    `.ajax()`是核心方法,支持GET和POST请求,还有`.load()`、`.getJSON()`等简化的API。`.ajaxStart()`和`.ajaxStop()`等方法可以监听Ajax请求的状态。 **jQuery 1.4.1中文手册** `jQueryAPI-100214.chm`是开发者的...

Global site tag (gtag.js) - Google Analytics