190

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

有人可以指出一些解决此问题的示例跨浏览器代码(Firefox、Opera、Safari、IE ......)吗?我熟悉 Firefox 的pageshow事件,但不幸的是 Opera 和 Safari 都没有实现这一点。

4

15 回答 15

123

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

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

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

默认情况下,它什么也不做。但不知何故,这似乎触发了 Safari、Opera 和 Mozilla 的重新加载——无论事件处理程序包含什么。

[编辑(Nickolay):这就是它以这种方式工作的原因:webkit.orgdeveloper.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>

使用 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>
于 2008-10-14T14:32:27.130 回答
81

一些现代浏览器(Firefox、Safari 和 Opera,但不包括 Chrome)支持特殊的“后退/前进”缓存(我称之为 bfcache,这是 Mozilla 发明的一个术语),在用户导航返回时涉及。与常规(HTTP)缓存不同,它捕获页面的完整状态(包括 JS、DOM 的状态)。这允许它更快地重新加载页面,并且与用户离开它时完全一样。

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

这也是为什么添加“卸载”处理程序会阻止页面存储在 bfcache 中(从而使其导航回更慢) - 卸载处理程序可以执行清理任务,这可能会使页面处于不可用状态。

对于需要知道何时离开/返回的页面,Firefox 1.5+ 和修复了错误 28758的 Safari 版本支持称为“pageshow”和“pagehide”的特殊事件。

参考:

于 2010-02-07T22:58:50.170 回答
31

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

经过一些测试,我发现点击返回的页面中元素的 readyState 不是“加载”而是“完成”。添加|| element.readyState == 'complete'到我的条件语句中解决了我的问题。

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

编辑完整性

我的代码如下所示:

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

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

于 2010-02-19T19:35:07.393 回答
22

好的,这是基于ckramer 的初始解决方案和palehorse 的示例的最终解决方案,适用于所有浏览器,包括Opera。如果您将 history.navigationMode 设置为“兼容”,那么 jQuery 的就绪功能将在 Opera 以及其他主要浏览器中的后退按钮操作上触发。

此页面有更多信息

例子:

history.navigationMode = 'compatible';
$(document).ready(function(){
  alert('test');
});

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

于 2008-10-04T15:07:06.000 回答
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>

每当我单击后退按钮时,它都会正确触发。

于 2012-05-31T23:22:16.640 回答
4

我可以确认 jQuery 的 ready 事件在 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>
于 2008-10-01T16:07:13.187 回答
4

如果我没记错的话,那么添加一个 unload() 事件意味着该页面无法被缓存(在前向/后向缓存中)——因为当用户离开时它的状态会发生变化/可能会发生变化。所以 - 当通过历史对象导航返回页面时恢复页面的最后一秒状态是不安全的。

于 2009-02-24T09:57:56.640 回答
4

我认为这将用于“onunload”,而不是页面加载,因为我们不是在谈论在点击“Back”时触发事件吗?$document.ready() 用于页面加载所需的事件,无论您如何到达该页面(即重定向、直接打开浏览器到 URL 等),而不是单击“返回”时,除非您正在说话关于再次加载时在上一页上触发的内容。而且我不确定页面没有被缓存,因为我发现 Javascripts 仍然存在,即使 $document.ready() 包含在其中。在编辑具有此事件的脚本时,我们必须按 Ctrl+F5 来修改它们,并且我们想在我们的页面中测试结果。

$(window).unload(function(){ alert('do unload stuff here'); }); 

是您在点击“返回”并卸载当前页面时想要的 onunload 事件,并且在用户关闭浏览器窗口时也会触发。这听起来更像是我们想要的,即使我的 $document.ready() 响应数量超过了我。基本上区别在于在当前页面关闭时触发的事件或在加载时单击“返回”时加载的事件。在 IE 7 中测试很好,不能代表其他浏览器,因为它们在我们所在的地方是不允许的。但这可能是另一种选择。

于 2011-02-16T15:54:43.663 回答
3

jQuery 的 ready事件就是为这类问题而创建的。您可能想深入研究实现以了解幕后情况。

于 2008-10-01T16:01:31.547 回答
3

对于不想使用整个 jquery 库的人,我在单独的代码中提取了实现。它只有 0.4 KB 大。

您可以在此 wiki 中找到代码以及德语教程:http ://www.easy-coding.de/wiki/html-ajax-und-co/onload-event-cross-browser-kompatibler-domcontentloaded.html

于 2010-09-11T09:52:18.900 回答
2

比尔,我敢回答你的问题,但我不能 100% 确定我的猜测。我认为当 IE 浏览器将用户带到历史页面时,它们不仅会从缓存中加载页面及其资源,而且还会为其恢复整个 DOM(读取会话)状态。IE 不执行 DOM 恢复(或至少不执行),因此 onload 事件看起来对于正确的页面重新初始化是必要的。

于 2008-10-01T16:04:35.063 回答
2

我使用 $(document).ready 尝试了 Bill 的解决方案...但起初它不起作用。我发现如果将脚本放在 html 部分之后,它将不起作用。如果它是 head 部分,它将起作用,但仅在 IE 中。该脚本在 Firefox 中不起作用。

于 2010-05-10T06:53:41.910 回答
1

好的,我试过了,它适用于 Firefox 3、Safari 3.1.1 和 IE7,但不适用于 Opera 9.52。
如果您使用下面显示的示例(基于palehorse 的示例),您会在页面首次加载时弹出一个警告框。但是,如果您随后转到另一个 URL,然后单击“后退”按钮返回此页面,则在 Opera 中不会弹出警告框(但在其他浏览器中会弹出)。

无论如何,我认为这已经足够接近了。谢谢大家!

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Untitled Document</title>
<meta http-equiv="expires" content="0">
<script src="jquery.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready( 
                    function(){
                      alert('test');
                    }
                 );
</script>
</head>
<body>
<h1>Test of the page load event and the Back button using jQuery</h1>
</body>
</html>
于 2008-10-01T16:37:13.100 回答
1

Unload 事件在 IE 9 上不能正常工作。我用 load 事件 (onload()) 进行了尝试,它在IE 9FF5上工作正常。

例子:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
    jQuery(window).bind("load", function() {
        $("[name=customerName]").val('');
    });
</script>
</head>
<body>
    <h1>body.jsp</h1>
    <form action="success.jsp">
        <div id="myDiv">

        Your Full Name: <input name="yourName" id="fullName"
            value="Your Full Name" /><br> <br> <input type="submit"><br>

        </div>

    </form>
</body>
</html>
于 2011-08-07T11:25:50.197 回答
1

我使用了一个 html 模板。在这个模板的 custom.js 文件中,有这样一个函数:

    jQuery(document).ready(function($) {

       $(window).on('load', function() {
          //...
       });

    });

但是当我转到其他页面后返回时,此功能不起作用。

所以,我试过了,它奏效了:

    jQuery(document).ready(function($) {
       //...
    });

   //Window Load Start
   window.addEventListener('load', function() {
       jQuery(document).ready(function($) {
          //...
       });
   });

现在,我有 2 个“就绪”功能,但它没有给出任何错误,并且页面运行良好。

尽管如此,我必须声明它已经在 Windows 10 - Opera v53 和 Edge v42 上进行了测试,但没有在其他浏览器上进行测试。请记住这...

注意:jquery 版本是 3.3.1,迁移版本是 3.0.0

于 2018-07-01T19:46:09.817 回答