单击后退按钮时是否存在跨浏览器onload事件?

Bil*_*ill 180 javascript pageload

对于所有主流浏览器(IE除外),onload由于后退按钮操作,页面加载时不会触发JavaScript 事件 - 它仅在首次加载页面时触发.

有人能指出我解决这个问题的一些示例跨浏览器代码(Firefox,Opera,Safari,IE,...)吗?我很熟悉Firefox的pageshow活动,但不幸的是Opera和Safari都没有实现这一点.

use*_*621 115

伙计们,我发现JQuery只有一个效果:当按下后退按钮时页面被重新加载.这与" 准备好 " 无关.

这是如何运作的?好吧,JQuery添加了一个onunload事件监听器.

// http://code.jquery.com/jquery-latest.js
jQuery(window).bind("unload", function() { // ...
Run Code Online (Sandbox Code Playgroud)

默认情况下,它什么都不做.但不知何故,这似乎会触发Safari,Opera和Mozilla的重装 - 无论事件处理程序包含什么.

[ 编辑(Nickolay):这就是为什么它的工作原理:webkit.org,developer.mozilla.org.请阅读这些文章(或我在下面单独的答案中的摘要),并考虑您是否真的需要这样做,并使您的页面加载速度较慢的用户.

不敢相信吗?试试这个:

<body onunload=""><!-- This does the trick -->
<script type="text/javascript">
    alert('first load / reload');
    window.onload = function(){alert('onload')};
</script>
<a href="http://stackoverflow.com">click me, then press the back button</a>
</body>
Run Code Online (Sandbox Code Playgroud)

使用JQuery时会看到类似的结果.

您可能希望在没有onunload的情况下与此进行比较

<body><!-- Will not reload on back button -->
<script type="text/javascript">
    alert('first load / reload');
    window.onload = function(){alert('onload')};
</script>
<a href="http://stackoverflow.com">click me, then press the back button</a>
</body>
Run Code Online (Sandbox Code Playgroud)

  • 答案似乎不适用于现代浏览器 - 在最新的Chrome和Opera中查看 (14认同)
  • 它在iPad游戏中无效...请将此作为答案取消标记 (10认同)
  • 这也有效(不要忘记onunload =""部分,否则将无法在ff3上工作):<body onload ="alert('onload');" onunload的= ""> (3认同)
  • 这是因为浏览器假设页面是不可缓存的,如果它有一个`onunload`处理程序(页面已经破坏了所有内容;为什么要缓存它?). (3认同)

Nic*_*lay 74

一些现代浏览器(Firefox,Safari和Opera,但不支持Chrome)支持特殊的"后退/前进"缓存(我称之为bfcache,这是Mozilla发明的术语),当用户导航Back时会涉及.与常规(HTTP)缓存不同,它捕获页面的完整状态(包括JS,DOM的状态).这使得它可以更快,更准确地重新加载页面,就像用户离开它一样.

load从该bfcache加载页面时,不应该触发该事件.例如,如果您在"加载"处理程序中创建了UI,并且在初始加载时触发了"load"事件,并且第二次从bfcache重新加载页面时,页面最终将以重复的UI元素.

这也是为什么添加"卸载"处理程序会阻止页面存储在bfcache中(从而使其导航速度变慢) - 卸载处理程序可以执行清理任务,这可能会使页面处于不可操作状态.

对于需要知道何时被导航/返回的页面,Firefox 1.5+和带有修复bug 28758的Safari版本支持称为"pageshow"和"pagehide"的特殊事件.

参考文献:


Bri*_*ese 31

我遇到了一个问题,当用户点击后退或前进时,我的js没有执行.我首先开始停止浏览器缓存,但这似乎不是问题.我的javascript设置为在加载所有库等之后执行.我用readyStateChange事件检查了这些.

经过一些测试后,我发现在单击后面的页面中元素的readyState不是"已加载"而是"完成".添加|| element.readyState == 'complete'到我的条件语句解决了我的问题.

只是想我会分享我的发现,希望他们会帮助别人.

编辑完整性

我的代码如下:

script.onreadystatechange(function(){ 
   if(script.readyState == 'loaded' || script.readyState == 'complete') {
      // call code to execute here.
   } 
});
Run Code Online (Sandbox Code Playgroud)

在上面的代码示例中,脚本变量是一个新创建的脚本元素,它已添加到DOM中.

  • 你在哪里添加这个?在用户击退后你是如何得到任何东西的?请告诉我们一些代码! (7认同)

Bil*_*ill 21

好的,这是基于ckramer初始解决方案的最终解决方案,以及适用于所有浏览器的Palehorse示例,包括Opera.如果将history.navigationMode设置为'compatible',则jQuery的ready函数将在Opera以及其他主要浏览器的Back按钮操作中触发.

此页面包含更多信息.

例:

history.navigationMode = 'compatible';
$(document).ready(function(){
  alert('test');
});
Run Code Online (Sandbox Code Playgroud)

我在Opera 9.5,IE7,FF3和Safari中对它进行了测试,它适用于所有这些.

  • 显然它已经有一段时间了(大约5.5年),但值得注意的是你的链接已经死了. (2认同)
  • 这个解决方案对我不起作用.我在最新的Firefox(45.0.1)中遇到过这个问题 (2认同)

小智 6

我无法让上面的例子起作用.我只是想在通过后退按钮返回页面时触发某些修改过的div区域的刷新.我使用的技巧是一旦div区域从原始区域改变,就将隐藏的输入字段(称为"脏位")设置为1.当我点击返回时隐藏的输入字段实际上保留了它的值,所以onload我可以检查这个位.如果已设置,我刷新页面(或只刷新div).但是,在原始负载上,该位未设置,因此我不会浪费时间加载页面两次.

<input type='hidden' id='dirty'>

<script>
$(document).ready(function() {
  if ($('#dirty').val()) {
    // ... reload the page or specific divs only
  }
  // when something modifies a div that needs to be refreshed, set dirty=1
  $('#dirty').val('1');
});
</script>
Run Code Online (Sandbox Code Playgroud)

每当我点击后退按钮时它都会正确触发.

  • 虽然这在Firefox中不起作用,但我认为这是处理IE/Chrome中的情况的一种巧妙方式,其中隐藏字段的持久性非常有用.我已经使用了你的技巧和"pageshow"事件,因此我涵盖了所有主要的浏览器. (3认同)

pal*_*rse 5

我可以向 ckramer 确认 jQuery 的就绪事件可以在 IE 和 FireFox 中运行。这是一个示例:

<html>
<head>
    <title>Test Page</title>
    <script src="http://code.jquery.com/jquery-latest.js" type="text/javascript"></script>
    <script type="text/javascript">
            $(document).ready(function () {
               var d = new Date();
               $('#test').html( "Hi at " + d.toString() );
            });
    </script>
</head>
<body>
    <div id="test"></div>
    <div>
        <a href="http://www.google.com">Go!</a>
    </div>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)