浏览器页面进入、离开事件:pageshow / pagehide
Firefox 和 Opera 有一个新特性,名叫 往返缓存(back-forward cache,或 bfcache),可以在用户使用浏览器的 后退 和 前进 按钮时加快页面的转换速度。这个缓存中不仅保存着页面数据,还保存了 DOM 和 JavaScript 的状态;实际上是将整个页面都保存在了内存里。如果页面位于 bfcache 中,那么再次打开该页面就不会触发load事件。尽管由于内存中保存了整个页面的状态,不触发 load 事件也不应该会导致什么问题,但为了更形象地说明 bfcache 的行为,Firefox 还是提供了一些新事件。
第一个事件就是 pageshow,这个事件在页面显示时触发,无论页面是否来自 bfcache。在重新加载页面中,pageshow 会在 load 事件触发后触发;而对于 bfcache 中的页面,pageshow 会在页面状态完全恢复的那一刻触发。另外要注意的是,虽然这个事件的目标是 document,但必须将其事件处理程序添加到 window。来看下面的例子:
var EventUtil = {
addHandler: function (element, type, handler) {
if (element.addEventListener) {
element.addEventListener(type, handler, false);
} else if (element.attachEvent) {
element.attachEvent("on" + type, handler);
} else {
element["on" + type] = handler;
}
}
};
(function () {
var showCount = 0;
EventUtil.addHandler(window, "load", function () {
alert("Load fired");
});
EventUtil.addHandler(window, "pageshow", function (event) {
showCount++;
alert("Show has been fired " + showCount + " times.");
});
})();
这个例子使用了私有作用域,以防止变量 showCount 进入全局作用域。当页面首次加载完成时,showCount 的值为 0。此后,每当触发 pageshow 事件,showCount 的值就会递增并通过警告框显示出来。如果你在离开包含以上代码的页面之后,又单击 后退 按钮返回该页面,就会看到 showCount 每次递增的值。这是因为该变量的状态,乃至整个页面的状态,都保存在了内存中,当你返回这个页面时,它们的状态得到了恢复。如果你单击了浏览器的“刷新”按钮,那么 showCount 的值会被重置为 0,因为页面已经完全重新加载了。
除了通常的属性之外,pageshow 事件的 event 对象还包含一个名为 persisted 的布尔值属性。如果页面中保存在了bfcache中,则这个属性的值为true;否则,这个属性的值为false。可以像下面这样在事件处理程序中检测这个属性:
var EventUtil = {
addHandler: function (element, type, handler) {
if (element.addEventListener) {
element.addEventListener(type, handler, false);
} else if (element.attachEvent) {
element.attachEvent("on" + type, handler);
} else {
element["on" + type] = handler;
}
}
};
(function () {
var showCount = 0;
EventUtil.addHandler(window, "load", function () {
alert("Load fired");
});
EventUtil.addHandler(window, "pageshow", function (event) {
showCount++;
alert("Show has been fired " + showCount + " times.Persisted? " + event.persisted);
});
})();
通过检测 persisted 属性,就可以根据页面在 bfcache 中的状态来确定是否需要采取其它操作。
与 pageshow 事件对应的是 pagehide 事件,该事件会在浏览器卸载页面的时候触发,而且是在 unload 事件之前触发。与 pageshow 事件一样,pagehide 在 document 上面触发,但其事件处理程序必须要添加到 Windows 对象。这个事件的 event 对象也包含 persisted 属性,不过其用途稍有不同,来看下面的例子:
var EventUtil = {
addHandler: function (element, type, handler) {
if (element.addEventListener) {
element.addEventListener(type, handler, false);
} else if (element.attachEvent) {
element.attachEvent("on" + type, handler);
} else {
element["on" + type] = handler;
}
}
};
EventUtil.addHandler(window, "pagehide", function (event) {
alert("Hiding. Persisted? " + event.persisted);
});
有时候,可能需要在 pagehide 事件触发时根据 persisted 的值采取不同的操作。对于 pageshow 事件,如果页面是从 bfcache 中加载的,那么 persisted 的值就是 true;对于 pagehide 事件,如果页面在加载之后会保存在 bfcache 中,那么 persisted 的值也会被设置为ture。因此,当第一次触发 pageshow 时,persisted 的值一定是 false,而在第一次触发pagehide时,persisted 就会变成 true(除非页面不会保存在 bfcache 中)。
指定了 onunload 事件处理程序的页面会被自动排除在bfcache之外,即使事件处理程序是空的。原因在于,onunload最常用于撤销在onload中所执行的操作,而跳过onload后再次显示页面很可能会导致页面不正常。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
上一篇: 前端开发工程师需要明白的 像素 知识
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论