回到 Firefox 历史后,JavaScript 将无法运行

IT技术 javascript firefox
2021-01-30 06:03:40

当我使用 Firefox 上的后退按钮到达以前访问过的页面时,该页面上的脚本将不会再次运行

第二次查看页面时,是否有任何修复/解决方法可以让脚本再次执行?

请注意,我已经在 Google Chrome 和 Internet Explorer 上测试了相同的页面,并且它们按预期工作。


以下是我用来测试问题的文件和步骤:

(导航到 0.html,点击进入 1.html,返回按钮)

0.html

<html><body>
<script>
  window.onload = function() { alert('window.onload alert'); };
  alert('inline alert');
</script>
<a href="1.html">Click Me!</a>
</body></html>

1.html

<html><body>
<p>Go BACK!</p>
</body></html>
6个回答

设置要在 window.onunload 上调用的空函数:

window.onunload = function(){}; 

例如

<html><body>
<script type="text/javascript">
  window.onload = function() { alert('window.onload alert'); };
  window.onunload = function(){};
  alert('inline alert');
</script>
<a href="1.html">Click Me!</a>
</body></html>

来源: http : //www.firefoxanswer.com/firefox/672-firefoxanswer.html (存档版)

您没有覆盖任何内容,这只是阻止 Firefox 在 Back-Forward Cache (bfcache) 中缓存页面。developer.mozilla.org/en/DOM/window.onunload developer.mozilla.org/En/Using_Firefox_1.5_caching
2021-03-15 06:03:40
好的,谢谢,我会调查的。再次感谢您,这个问题一直困扰着我一段时间:)
2021-03-19 06:03:40
虽然它应该打破 bfcache 不幸的是它似乎仍然记得上一页 - 特别是,当你返回时再次加载加载的 iframe url,如果需要将生成的内容放置在框架中,似乎没有跨浏览器重新刷新的方式。
2021-03-22 06:03:40
有人知道为什么 FireFox 需要这个而其他浏览器不需要吗?
2021-03-24 06:03:40
谢谢,它有效。关于默认 onunload 处理程序做什么的任何提示?(例如,我是否在这里覆盖了某种默认行为?)
2021-04-01 06:03:40

当我使用 Firefox 上的后退按钮到达以前访问过的页面时,该页面上的脚本将不会再次运行。

这是正确的,这是一件好事。

当您在 Firefox(以及 Safari 和 Opera)中点击链接时,它不会立即破坏您的页面以进入下一个页面。它使页面保持完整,只是将其隐藏起来。如果您点击后退按钮,它会重新显示旧页面,而无需再次加载文档;这要快得多,从而为用户带来更平滑的后退/前进页面过渡。

此功能称为bfcache

您在用户之前加载和使用页面期间添加到页面的任何内容仍将存在。您附加到页面元素的任何事件处理程序仍将被附加。您设置的任何超时/间隔仍将处于活动状态。因此,您几乎没有任何理由需要知道自己已被隐藏并重新显示。onload再次调用或内联脚本代码是错误的,因为您在该函数中所做的任何绑定和内容生成都会对相同的内容再次执行,这可能会导致灾难性的结果。(例如document.write,内联脚本会完全破坏页面。)

写入window.onunload有影响的原因是实现 bfcache 的浏览器已经决定——为了与真正需要知道它们何时被丢弃的页面兼容——任何声明有兴趣知道何时onunload发生的页面都会导致 bfcache被禁用。该页面将在您返回时重新加载,而不是从 bfcache 中获取。

所以如果你设置了window.onunload= function() {};,你实际上在做的是故意破坏 bfcache。这将导致您的页面导航缓慢,除非作为最后的手段,否则不应使用。

如果您确实需要知道用户何时离开或返回您的页面,而又不弄乱 bfcache,您可以改为捕获onpageshowonpagehide事件:

window.onload=window.onpageshow= function() {
    alert('Hello!');
};
@Jimbo:请测试用例。bfcache 旨在(并且在我见过的每种情况下,确实如此)通过隐藏/显示保留 DOM 的确切状态。当页面返回时,已淡入的元素将保持不透明,除非其他脚本运行以再次隐藏它。
2021-03-19 06:03:40
bfcache 通常应该返回整个页面,就像它离开时一样。从上一页返回后丢失的内容是什么?(测试用例?)的document.ready工作方式与window.onload(对于某些浏览器而言,无论如何它们都是相同的事件)基本相同。
2021-03-22 06:03:40
我的问题是 bfcache 没有缓存所有页面,所以我必须重新运行 js 来重建丢失的内容。所以颠簸整个页面可能没问题。无论如何,我没有使用 window.onload 事件,我使用的是 jQuery document.ready 事件。您知道仍然可以使用 document.ready 并避免此问题的方法吗?
2021-03-25 06:03:40
@bobince - 使用 CSS 文件创建一个元素,将不透明度设置为零,然后使用一些 jQuery 使其淡入准备就绪的文档。回到历史后,它将重新应用样式表 CSS(零),而不会保留 JS 在淡入时添加到样式属性的 opacity:1。第一次访问页面时,元素将从 0 淡入到 1。转到另一个页面并回击,它会完全透明地坐在那里。
2021-04-05 06:03:40
这不是一件好事,因为它不会再次运行 javascript,考虑到它已缓存……但实际上并没有缓存 javascript 之前所做的更改。如果 javascript 在页面加载时淡入一个元素,它在历史访问时不会再次淡化它......但会再次以 0 不透明度启动它,撤消 javascript 所做的事情!它必须是全有或全无。如果您想在不再次运行 javascript 的情况下显示缓存页面,则必须在 javascript 运行后缓存页面的完整状态!
2021-04-09 06:03:40

您可以检查事件persisted属性pageshow它在初始页面加载时设置为 false。当页面从缓存加载时,它被设置为 true。

window.onpageshow = function(event) {
    if (event.persisted) {
        alert("From bfcache");
    }
};

出于某种原因,jQuery 在事件中没有这个属性。不过,您可以从原始事件中找到它。

$(window).bind("pageshow", function(event) {
    if (event.originalEvent.persisted) {
        alert("From bfcache");
    }
});
这在 Chrome 58.0.3029.110(64 位)和 FF 53.0.2(64 位)中对我有用,没有任何更改。
2021-03-19 06:03:40
感谢您提供 javascript 和 jquery 版本!你在最后错过了一个右括号(这不是呻吟!)。我还要注意,为了其他人,IE 和 Chrome 报告 .persisted 总是错误的,无论如何。
2021-04-05 06:03:40
正如 Magnus 所指出的,在我删除 if 语句之前,这在 Chrome 中对我不起作用。
2021-04-08 06:03:40

当用户使用浏览器历史记录返回页面时,使页面执行 JavaScript 的一种简单方法是 OnPopState 事件。我们使用它来暂停和重播我们主页 ( https://fynydd.com )上的视频

window.onpopstate = function() {

    // Do stuff here...
};

连接一个什么都不做的“onunload”事件:

<html><body>
<script type="text/javascript">
  window.onload = function() { alert('window.onload alert'); };
  window.onunload = function(){}; 
  alert('inline alert');
</script>
<a href="1.html">Click Me!</a>
</body></html>
@dreagan,这会禁用 bfcache,但不一定禁用 HTTP 缓存。HTTP 缓存有一套完整的其他规则。如果你在那里抛出一个服务器端睡眠,你应该在点击返回时注意到它。Mozilla 在他们关于 BFCache常见问题解答的第三个问题中谈到了这一点
2021-03-12 06:03:40
您应该添加到您的答案中,将 onunload 事件添加到您的页面实际上会禁用整个缓存的页面。这不仅仅是让 JS 再次运行,它还会使服务器负载上升一个档次。这真的不是一个可以掉以轻心的建议,这一点应该慎重考虑。
2021-03-20 06:03:40
不确定,我投了赞成票,看起来有人对这个问题的每个答案都投了反对票......
2021-04-08 06:03:40
我说的是 BFcache,应该已经指定了。这并不意味着您应该在不通知 OP 后果的情况下给出这样的建议。另一种方法是使用 onpopstate 事件尝试再次触发 javascript。
2021-04-09 06:03:40
我还是不知道我是否理解。如果客户端的本地 bfcache 被绕过,为什么“服务器负载会上升一个档次”?是的,DOM 需要重建,但 HTML 应该是客户端 HTTP 缓存的一部分。是的,需要重新加载额外的资源,但这些资源也应该是客户端 HTTP 缓存的一部分。至于onpopstate,当这个问题在大约五年前被问到时,该事件仍然相对较新,浏览器支持非常不一致。
2021-04-11 06:03:40