JavaScript-bfcache/pageshowevent-event.persisted始终设置为false
JavaScript - bfcache/pageshow event - event.persisted always set to false?
在一个标准的Java/SpringMVC/JSP/jQuery web应用程序中,我试图检测一个"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>
我正在运行OpenSUSE Linux,并在FireFox和Chrome(最新版本)中尝试过这一点,但每次事件的persisted
属性设置为false
时(我可以在JavaScript控制台和上面代码中弹出的警报中看到这一点)。每次,我的意思是,无论它是从服务器加载的,还是通过"后退"按钮(或"后退"链接)再次显示的。
如果页面是通过Back按钮或history.go(-1)
调用显示的,我的意图是进行AJAX调用,用来自服务器的更新数据重新加载摘要组件/面板。
我还尝试设置一个卸载处理程序(它什么都不做)来防止页面被放入bfcache,但它似乎仍然显示bf缓存的版本,并且event.persisted
(或event.originalEvent.persisted
)被设置为false
。
这个属性在Linux上管理正确吗?我在代码中做了什么愚蠢的事情吗?任何帮助或想法都将不胜感激,谢谢!
我发现隐藏的输入按钮不是一个可靠的解决方案,因为当用户导航回页面并点击刷新时,它们可能包含错误的值。有些浏览器(Firefox)在刷新时保留输入值,因此每当用户点击刷新时,它都会再次刷新,因为输入按钮包含错误的值。这是论坛的典型场景(用户查看主题,点击后退按钮返回主题列表,然后可能继续点击刷新以检查是否有新主题)。
正如Grégoire Clermont所指出的,event.persisted
在chrome(和IE)中存在漏洞,截至2017年2月,这两种浏览器都尚未修复。好消息是,chrome和IE可以依赖window.performance.navigation.type == 2
。具有讽刺意味的是,Firefox对后者来说不可靠,但这并不重要,因为它对event.persisted
来说是可靠的。以下代码对我有效:
if (document.addEventListener) {
window.addEventListener('pageshow', function (event) {
if (event.persisted || window.performance &&
window.performance.navigation.type == 2)
{
location.reload();
}
},
false);
}
2022年更新:
由于window.performance.navigation.type
已弃用(参考号:MDN),我更新了代码以执行相同的操作:
if (document.addEventListener) {
window.addEventListener('pageshow', function (event) {
if (event.persisted || performance.getEntriesByType("navigation")[0].type === 'back_forward') {
location.reload();
}
},
false);
}
这似乎是Chrome中的一个错误(IE11中也存在)。
我找到了以下解决方法:
<input type="hidden" id="cacheTest"></input>
<script>
var input = document.querySelector('#cacheTest')
if (input.value === "") {
// the page has been loaded from the server,
// equivalent of persisted == false
}
else {
// the page has been loaded from the cache,
// equivalent of persisted == true
}
// change the input value so that we can detect
// if the page is reloaded from cache later
input.value = "some value"
</script>
这利用了这样一个事实,即在大多数浏览器中,当从缓存加载页面时,表单字段值也会被保存。
我知道这有点晚了,但这对我来说很有效:
window.onpageshow = function(e) {
if (e.persisted) {
alert("Page shown");
window.location.reload();
}
};
我认为您在文档准备功能中不需要它,只需使用香草即可。
- 如何在angularJS中编辑时,如果DB中的值为true,则设置复选框,如果值为false,则取消选中复选框
- 如何将localStorage值设置为false
- 如何使用javascript将字段强制设置为false
- 为什么当async标志设置为false时,xmlhttprequest中的代码可以工作,而当它设置为true时却不能工作
- 如何通过Javascript启用链接按钮最初设置为Enable=false
- 当可见属性设置为 false 时,使用 JavaScript 删除空格
- 至于所有输入的标签都用指定的属性来设置,例如属性检查=false
- 如何使函数将属性值从 FALSE 设置为 TRUE
- 如果循环中至少有一个元素返回 false,如何将变量设置为 false
- 如何添加 Object.prototype.x?设置为 enumerable:false
- jqgrid在条件下动态设置单元格可编辑false
- Unity 3d事件触发器将gameobject.active设置为false
- 单击命令按钮后需要设置rich:simpleTogglePanel open=false
- 将DIV ID内的所有链接设置为返回false
- 在unslider.js中设置true或false
- 如何为 jqPlot 中的特定数据系列设置 Stack Series false
- 无法获取 document.getElementById(“wp_mep_1”).autoplay=false;以在设置
- 为什么从指令中更改外部作用域需要 scope.$apply(),即使我将范围选项设置为 false
- angular I只能设置'true'on'ng-if'但我可以't设置`false'
- 覆盖保留字(设置 false = true)