我正在尝试检测当前页面是从缓存加载还是新的副本。
我的body标签上注册了onPageShow回调。我可以看到它被触发了,但是我无法提供一种event.persisted实际上为真的情况。
我什至将Firefox置于离线模式,并且看到响应是从“网络”选项卡上的缓存中获取的,但是event.persisted仍然为false。
在标准的Java/SpringMVC/JSP/jQuery web-app中,我试图检测"Back"(或history.go(-1))事件,以便刷新(AJAX)摘要组件/面板内容时我返回到一个页面(我们可以在其中更改摘要组件显示的后端数据).
我在JavaScript中尝试了以下内容(关于StackExchange上的一些帖子,重新如何实现这一点):
<script type="text/javascript">
$(document).ready(function() {
window.onpageshow = function(event) {
console.log("Event:");
console.dir(event);
if (event.persisted) {
alert("non-jQuery - back to page - loaded from bfcache");
} else {
alert("non-jQuery - loaded page from server");
}
};
$(window).on("pageshow", function(event){
console.log("Event:");
console.dir(event);
if (event.originalEvent.persisted) {
alert("jquery - back to page - loaded from bfcache");
} else {
alert("jquery - loaded page from server");
}
});
});
</script>
Run Code Online (Sandbox Code Playgroud)
我正在运行OpenSUSE Linux并尝试使用FireFox和Chrome(最新版本),但每次将事件的persisted属性设置为false(我可以在JavaScript控制台中看到这一点,以及从上面的代码弹出的警报).每次,我的意思是,无论是从服务器加载还是通过后退按钮(或"后退"链接)再次显示.
我的目的是进行AJAX调用,如果通过"后退"按钮或history.go(-1)调用显示页面,则使用服务器的更新数据重新加载摘要组件/面板.
我也试过设置一个卸载处理程序(什么也不做),以防止页面被放入bfcache,但它似乎仍然显示bf-cached版本,并且event.persisted(或event.originalEvent.persisted)设置为false …
Mobile Safari使用一种特殊的缓存机制Page Cache(在此),该机制基本上使当前页面保持活动状态,但是当我们导航到另一个页面时处于休眠状态。这样,当用户按下back按钮时,它可以立即以最新状态显示上一页。
这对于导航和浏览Web很有用,但是在特殊情况下,这变得很烦人,因为每次用户导航到该页面时,您可能需要获取该页面的新副本。(就我而言,我必须进入以下页面:登录名和主页)。
我完全知道,没有什么可以阻止用户打开同一应用程序的多个选项卡。我对此并不担心。
在防止页面被缓存的跨浏览器的解决方案并不能帮助如Safari是保持页面打开,但无形的暂停。
该window.onpageshow和处理event.persisted没有帮助,因为它似乎在浏览器不执行onpageshow某些原因事件第二次(当你按下back按钮)。
对于那些不知道onpageshow事件是什么的人请注意:Apple不鼓励使用loadand unload事件,因为使用页面缓存的概念,这些事件没有明确的意义。因此,onpageshow应该做我们期望的load事件。
在我的第一个jQuery Mobile应用程序上工作.有一个localStorage值必须在整个应用程序中有一个值,所以我点击了pageshow事件来检查这个值:
$(function () {
$("div[data-role='page']").on("pageshow", function (event, ui) {
if (getValue() == null) {
// show the dialog
$.mobile.changePage("#dialog");
}
});
});
Run Code Online (Sandbox Code Playgroud)
这在浏览各个页面时有效,但在第一页加载时永远不会被调用.我试图在我添加pageshow监听器的部分下面再次复制上面的If语句,但它具有显示对话框,隐藏它,然后再次显示它的效果.
在第一页上,似乎打开对话框正在触发pageshow(这很奇怪,考虑到我的选择器),这又触发了另一个对话框.有没有人有关于如何解决这个问题的建议,或者更好的方式来解决整个问题?
更新#1:我试过了
$.mobile.changePage( "#mypage", { allowSamePageTransition: true, transition: "none" } );
Run Code Online (Sandbox Code Playgroud)
但它与原始问题具有相同的效果,它启动对话框,然后隐藏它,然后再次显示它.似乎以某种方式启动对话框正在触发pageshow事件,即使我试图在我的选择器中过滤掉它.请注意,如果删除转换:"none"选项,则根本不显示该对话框.
更新#2:我还试图创建一个空白的初始页面,然后进行简单的页面转换
$.mobile.changePage("#mypage");
Run Code Online (Sandbox Code Playgroud)
但它仍然没有正确的行为.在这种情况下,它确实将我带到下一页,但是不会触发pageshow事件,因为我的对话框没有出现.我知道它没有触发,因为我可以从导航菜单中选择另一个页面,然后会出现对话框.
更新#3:我更改了我的选择器,我附加了pageshow监听器.我没有选择data-role ="page"的位置,而是按照ID选择特定的页面.然后我重新尝试了我在前两次更新中描述的两种方法,但它仍然无法正常工作.首先,当我尝试使用allowSamePageTransition刷新初始页面时,似乎pageshow会触发两次,因为对话框会启动两次.然后,当我尝试使用空白的初始页面,然后在我附加pageshow监听器后立即进行重定向时,没有任何反应,对话框永远不会出现.如果我导航到任何其他页面,该对话框将按预期工作.我不明白为什么这第一页太麻烦了.