如何让Firefox从其他域上的页面返回时触发popstate事件?

时间:2012-10-11 13:18:56

标签: javascript firefox javascript-events popstate

我有一个简单的网页,即:

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>History hacks</title>
<script>
window.onpopstate = function (e) {
    alert("location: " + document.location + ", state: " + JSON.stringify(e.state));
}
window.onload = function (e) {
    alert('page loaded');
}
</script>
</head>
<body>
<p> <a href="http://www.yahoo.com">Yahoo</a> <a href="#part1">Part 1</a></p>
</body>
</html>

现在关于Chrome和Firefox如何触发popstate事件有很多不同之处(当我开始测试IE时,我不禁想到我遇到了什么),但是给我带来问题的是Chrome会每当我点击这两个链接中的任何一个时触发一个popstate事件,然后当我点击后退按钮时再触发一个popstate事件。 Firefox将触发更改散列部分的链接事件(仅在哈希链接相同时才第一次),如果单击Yahoo链接然后单击后退按钮,则根本不会触发它。

那么有一种方法我可以在Firefox中告诉用户刚刚点击并从另一个域上完全不同的网站返回我的页面吗?还有另一个可以在Firefox中用于此目的的事件吗? (当我从yahoo.com返回时,加载事件不会被触发。)

4 个答案:

答案 0 :(得分:11)

要使用后退(或前进)按钮转到初始页面加载时获取popstate事件,请使用{/ 1}}

replaceState()

要忽略Chrome加载页面时生成的初始window.onload = function(e) { history.replaceState(null, null, document.URL); } ,您可以在调用popstate / pushState时标记状态,例如

replaceState

然后,您的history.pushState({myTag: true}, null, url); 处理程序只会过滤popstate

myTag

您可以将这两者组合成一个简单的跨浏览器解决方案:

window.onpopstate = function(e) { 
  if (!e.state.myTag) return; // none of my business
  // code to handle popstate 
}

@Boris Zbarsky详细介绍了bfcache。我没有想过如何将它与我的方法结合起来。我只是通过adding a page unload handler

禁用它
window.onpopstate = function(e) { 
  if (!e.state.myTag) return; // none of my business
  // code to handle popstate 
}

window.onload = function(e) {
  history.replaceState({myTag: true}, null, document.URL);
}

答案 1 :(得分:2)

如果您希望在返回页面时收到通知,即使它已缓存在页面缓存中,您可能正在寻找pageshow事件。

请注意,如果没有load事件,也意味着该页面仍然具有与导航离开时完全相同的DOM和脚本执行环境。基本上就像用户切换标签一段时间,而不是导航。

所以考虑到这一点,你还想在那种情况下举办活动吗?当用户切换回包含您页面的选项卡时,您是否获得了您要查找的事件?

答案 2 :(得分:0)

卸载之前我重新加载我的页面(获取初始状态)然后设置新的href

&#13;
&#13;
window.onunload = function(e) {
  location.reload();
  location.href = **new_url** ;
}
&#13;
&#13;
&#13;

我必须这样做,因为firefox保存了我页面的最后状态并恢复它而不是重新创建它。

答案 3 :(得分:0)

我有同样的问题,不得不深入研究规格,以确定当使用后退按钮从不同域上的页面返回时,为什么popstate事件不会在任何浏览器中触发。事实证明,popstate不应该在这种情况下触发,因为文档的状态改变不正确,并且只有当状态改变为真时才会触发popstate。对于状态更改为设置为true spec说:

  

如果指定条目的Document具有最新条目,并且该条目不是指定条目,则将状态更改为true;否则就是假的。

我的理解是,当我们从不同域中的页面返回我们的页面时,由于文档已更改且新文档尚未进入最新条目,因此我们的页面没有最新条目。再次来自规范:

  

浏览上下文中的每个文档也可以包含最新条目。这是该文档的条目,浏览上下文的会话历史记录最近遍历该条目。创建文档时,它最初没有最新条目。

但是,仍然有一种方法可以通过使用历史记录的pushState或replaceState方法在页面中的history.state中设置标记并检查历史记录中是否存在此标记来查看用户是否已返回到您的页面。页面加载状态。

有关WHATWG的HTML规范的更多内容,请参阅处理popstate事件的部分: https://html.spec.whatwg.org/multipage/browsers.html#history-traversal