宝哥软件园

jQuery Mobile页面返回时没有重新获取

编辑:宝哥软件园 来源:互联网 时间:2021-11-02

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),其中主页面包含一个转向test1页面的链接(即标签),test1有一个属性为data-rel=“back”的链接和一个转向test2的链接,test2只有一个属性为data-rel=“back”。main转test1后,点击后退链接返回main(相当于点击浏览器的后退按钮),无需再次发送get请求;但是,当test1转到test2并单击test2页面上的后退链接返回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》的描述:

在DOM中缓存页面要在DOM中保留所有以前访问过的页面,请将页面插件上的domCache选项设置为true,就像这样: $ . mobile . page . prototype . options . DOM cache=true;或者,为了只缓存特定的页面,您可以将data-dom-cache='true '属性添加到页面的容器: div data-role=' page ' id=' cache me ' data-DOM-cache=' true '您也可以像这样以编程方式缓存页面: page containerelement . page({ domcache3360 true });DOM缓存的缺点是DOM会变得非常大,导致一些设备变慢和内存问题。如果您启用了DOM缓存,请注意自己管理DOM,并在一系列设备上进行彻底测试。

从这段引文中可以看出,三种方法都可以将页面缓存到dom中,所以我使用了第二种方法,即在页面的div中添加属性data-DOM-cache=“true”,但是出现了以下两个问题:

1.如下图所示,当我的访问路径为main-test1-test2-test1(test2由history.back()返回)时,我们可以看到test2仍然存在于firebug提供的dom中,结果如红色部分所述:DOM将变得非常大,这会降低页面速度,并在某些设备上造成内存错误。

2.当我有这样一个页面时,它通过不同的参数显示不同的内容,页面上有一个js脚本,会对页面上的元素做一些处理。但是,我们常用的方法是使用id来获取目标元素。因为我们使用缓存来缓存页面,所以会导致js事件或者操作混乱。例如,在这里,我添加了一个test1_1页面,其内容几乎与test1相同。它们都有相同id和按钮的div来处理相同的事件。这个事件的作用是向这个div添加内容。当访问路径为main-test1-test1_1时,点击test1_1上的按钮,你会发现这个事件似乎没有被触发,但是已经被触发了,只有内容被添加到test1中的div中。

因此,对于大多数当前的应用程序,除非您自己管理dom中页面的生命周期,否则这种方案是不可取的。

最佳建议

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

(函数($,未定义){$.fn .子页=函数(选项){$(文档)。bind('pagebeforeshow ',function(){ var forward=$ . mobile . urlshistory . getnext();if(forward){ var DataURl=forward . URl;var forward page=$ . mobile . page container . children(' : jqmdata(URL=' dataUrl ' ')')));if(ForWordPage){ ForWordPage . remove();} } $ . mobile . urlshistory . clearforward();});};$(文档)。bind('pagecreate create ',函数(e) {$(':jqmData(role='page ')',e.target)。子页();});})(jQuery);因此,页面返回时出现js脚本错误,如下图所示:

那么是什么原因呢?如果我们不处理这个事件,我们将在哪里处理它?于是我仔细研究了jQuery Mobile的源代码,发现了下面这段话:

过渡页(转页,从页,设置。过渡,设置。反转)。done(function(){ removeActiveLinkClass();//如果有一个重复的scheduled page,现在它是hiddenif(settings . replicatescheduled page){ settings . replicatescheduled page . remove();}//移除初始构建类(仅在第一页显示)$ html . remove class(' ui-mobile-rendering ');releasePageTransitionLock();//让听众知道我们都更改完了当前的page.mpc.trigger('pagechange ',trigger data);});页面切换后会触发pagechange事件,所以我把pagebeforeshow改成了pagechange。一切按预期运行,没有错误。终于,我完成了。

摘要

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

1.在引用脚本之前,必须引用jquery和jquery移动脚本文件;

2.必须将data-dom-cache='true '添加到页面中。

以上是边肖介绍的jQuery Mobile页面不需要再次获取的描述,希望对大家有所帮助!

更多资讯
游戏推荐
更多+