7

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

<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 任何时候触发一个事件我单击这两个链接中的任何一个,然后在单击返回按钮时再次单击。Firefox 将触发更改哈希部分的链接的事件(如果哈希链接相同,则仅是第一次),如果我单击 Yahoo 链接然后单击后退按钮,则根本不会触发它。

那么有没有一种方法可以让我在 Firefox 中判断用户刚刚从不同域的完全不同站点返回并返回我的页面?在 Firefox 中是否有其他事件可以用于此目的?(当我从 yahoo.com 返回时,也不会触发加载事件。)

4

4 回答 4

11

popstate在使用后退(或前进)按钮转到初始页面加载时获取事件,请使用replaceState()like

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

要忽略popstateChrome 在页面加载时生成的初始值,您可以在调用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 
}

您可以将这两者结合起来以获得简单的跨浏览器解决方案:

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);
}

@Boris Zbarsky 详细介绍了 bfcache。我还没有想过如何将它与我的方法结合起来。我只是通过添加页面unload处理程序来禁用它

window.onunload = function(e) { }
于 2012-10-12T21:14:34.653 回答
2

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

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

因此,鉴于此,您还想在这种情况下举办活动吗?当用户切换回包含您的页面的选项卡时,您是否收到了您要查找的事件?

于 2012-10-11T19:37:04.200 回答
0

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

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

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

于 2014-10-14T08:58:25.947 回答
0

我有同样的问题,不得不深入研究规范,以弄清楚为什么当使用后退按钮从不同域的页面返回时,popstate 事件不会在任何浏览器中触发。事实证明,在这种情况下 popstate 不应该触发,因为文档的 state changed 不是 true,并且 popstate 应该仅在 state changed 为 true 时触发。将状态更改为 true 规范说:

如果指定条目的 Document 有最新条目,并且该条目不是指定条目,则令 state changed 为真;否则让它为假。

我的理解是,当我们从不同域的页面返回到我们的页面时,我们的页面没有最新条目,因为文档已更改并且新文档还没有最新条目。再次来自规范:

浏览上下文中的每个文档也可以有一个最新条目。这是浏览上下文的会话历史最近被遍历到的那个 Document 的条目。创建文档时,它最初没有最新条目。

但是,仍然有一种方法可以查看用户是否返回到您的页面,方法是使用 history 的 pushState 或 replaceState 方法在页面的 history.state 中设置标志,并在页面加载时检查 history.state 中是否存在此标志。

更多阅读 WHATWG 的 HTML 规范中处理 popstate 事件的部分: https ://html.spec.whatwg.org/multipage/browsers.html#history-traversal

于 2015-11-07T11:07:28.493 回答