如果您不想为添加到onpopstate的每个处理程序采取特殊措施,那么我的解决方案可能会对您有所帮助。这种解决方案的一个重要优点是,在页面加载完成之前就可以处理onpopstate事件。
在添加任何onpopstate处理程序之前只需要运行此代码一次,然后一切都应该按预期工作(就像在Mozilla中一样)。
(function() {
if (!window.addEventListener)
return;
var blockPopstateEvent = document.readyState!="complete";
window.addEventListener("load", function() {
setTimeout(function(){ blockPopstateEvent = false; }, 0);
}, false);
window.addEventListener("popstate", function(evt) {
if (blockPopstateEvent && document.readyState=="complete") {
evt.preventDefault();
evt.stopImmediatePropagation();
}
}, false);
})();
它是如何工作的:
Chrome、Safari以及可能其他基于Webkit内核的浏览器会在文档加载完成后触发onpopstate事件。这并不是预期的行为,因此我们阻止popstate事件直到文档加载完成后第一个事件循环周期。这是通过preventDefault和stopImmediatePropagation调用实现的(与stopPropagation不同,stopImmediatePropagation可以立即停止所有事件处理程序的调用)。
然而,由于Chrome在文档加载完成时已经处于“complete”状态,会错误地触发onpopstate事件,因此允许在文档加载完成之前已被触发的opopstate事件,在文档加载完成之前允许onpopstate的调用。
更新2014-04-23: 修复了一个bug,该bug导致如果脚本在页面加载后执行,则popstate事件将被阻止。