一些浏览器中返回按钮是直接使用缓存的,不会执行任何js代码,例如, 在提交的时候将按钮设置为loading状态,如果在提交成功后没有对按钮进行处理,那么返回后按钮依然是loading状态,这就很尴尬了。
原因:部分浏览器在后退时不会触发onload事件,這是HTML5世代浏览器新增的特性之一——Back-Forward Cache(简称bfcache)
什么是bfcache
《JavaScript高级程序设计》有提及bfcache:
bfcache,即back-forward cache,可称为“往返缓存”,可以在用户使用浏览器的“后退”和“前进”按钮时加快页面的转换速度。这个缓存不仅保存页面数据,还保存了DOM和JS的状态,实际上是将整个页面都保存在内存里。如果页面位于bfcache中,那么再次打开该页面就不会触发onload事件;
那怎么来解决这个问题呢?
小编查阅了各大资料,发现以下两个方法,亲测有效:
pageshow事件
这个事件在页面显示时触发,无论页面是否来自bfcache。在重新加载的页面中,pageshow会在load事件触发后触发;
而对于bfcache中的页面,pageshow会在页面状态完全恢复的那一刻触发。
如果是要在返回/后退页面的时候触发,就用pageshow事件:
实际项目中遇到在IOS系统下,ajax异步提交订单的时候因为抓的数据比较多,所以在提交比较慢,所以在提交的时候加上loading,但是提交过去之后如果返回到原来的页面发现loading还残留在,整个页面卡住不动了,用户体验骤减;
有了这两个事件,就可以在页面跳转前关闭loading或者在页面返回的时候关闭loading;代码:
var ddloading;
$.ajax({
url: _url,
type: 'post',
dataType: 'json',
data: _data,
beforeSend:function(){
ddloading=$.showDialog("{loading}");//$.showDialog()是项目内部的方法,包括下面的close()方法;
},
success: function (result) {
if (result.STATUS == "SUCCESS") {
//在location.href之前绑定,一旦location.href马上执行
$(window).on("pageshow",function(){
ddloading.close();
})
location.href = "/M/Product/OrderSuccess?orderId=" + result.DATA.OrderId;
}
}
});
pagehide事件
该事件会在浏览器卸载页面的时候触发,而且是在unload事件之前触发。
使用方法同pageshow,在页面跳转前触发:
var ddloading;
$.ajax({
url: _url,
type: 'post',
dataType: 'json',
data: _data,
beforeSend:function(){
ddloading=$.showDialog("{loading}");//$.showDialog()是项目内部的方法,包括下面的close()方法;
},
success: function (result) {
if (result.STATUS == "SUCCESS") {
//在location.href之前绑定,一旦location.href马上执行
$(window).on("pagehide",function(){
ddloading.close();
})
location.href = "/M/Product/OrderSuccess?orderId=" + result.DATA.OrderId;
}
}
});
persisted属性
pageshow事件和pagehide事件的event对象还包含一个名为persisted的布尔值属性。
- 对于pageshow事件,如果页面是从bfcache中加载的,则这个属性的值为true;否则,这个属性的值为false。
- 对于pagehide事件,如果页面在卸载之后被保存在bfcache中,则这个属性的值为true;否则,这个属性的值为false。
不同的浏览器在浏览器会在当前窗口“打开”历史纪录中的前一个页面的表现上并不统一,这和浏览器的实现以及页面本身的设置都有关系。
其他方法:
- beforeunload//页面离开前执行,PC端有效,手机端测试无效;可以阻止页面跳转;
- unload//在beforeunload之后执行,可以执行事件,但不能阻止页面跳转;