【问题标题】:Is there a cross-browser onload event when clicking the back button?单击后退按钮时是否存在跨浏览器 onload 事件?
【发布时间】:2010-09-14 13:43:55
【问题描述】:

对于所有主流浏览器(IE 除外),JavaScript onload 事件不会在页面加载时触发  -  它只会在页面首次加载时触发。

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

【问题讨论】:

  • 这不是问题 - 它允许在用户按下返回按钮时快速加载网页。有关详细信息,请参阅下面的答案。此处建议的解决方法使网页对用户来说更加烦人,因为向后/向前导航更慢。
  • @romkyns:您的评论与此问题无关。当浏览器不恢复 JS/DOM 状态时,它们会触发 load 事件。
  • iOS 5+ 历史返回按钮在这里解决stackoverflow.com/a/12652160/1090395

标签: javascript pageload


【解决方案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

【讨论】:

    【解决方案2】:

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

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

    这也是为什么添加“卸载”处理程序会阻止页面存储在 bfcache 中(从而使其导航回的速度变慢)——卸载处理程序可以执行清理任务,这可能会将页面留在无法工作的状态。

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

    参考资料:

    【讨论】:

    • 这很酷。我目前处于我的 dom 操作似乎没有保存在 bfcache 中的情况。在任何情况下,您可能会期待吗?
    • @Benson:我链接到的 dev.m.o 页面上列出了 Firefox 不会将您的页面保存在 bfcache 中的可能原因。我认为不可能将页面保存到 bfcache,但某些 DOM 状态不会被保存。
    • Nickolay,我知道您不愿意强制重新加载并撤消 bfcache 所做的出色工作,但是还有其他方法可以更新 bfcache 中页面的 dom 吗?例如,考虑我从包含消息列表的页面转到其中一个页面的情况,当我“返回”时,我希望更改已读/未读指示符。如何在不重新加载页面的情况下做到这一点?
    • @Greg:您的意思是作为控制页面的开发人员?从“pageshow”侦听器触发 ajax 请求。
    • 关于如何使用 jQuery 并获得快速 bfcache 支持的任何想法?
    【解决方案3】:

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

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

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

    完整编辑

    我的代码如下:

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

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

    【讨论】:

    • 你在哪里添加的?在用户回击后,你是如何让任何东西触发的?请给我们一些代码!
    • 你说“我的条件语句”是什么意思?
    • @Phillip 条件语句是 if 语句。
    【解决方案4】:

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

    此页面有more information

    例子:

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

    我在 Opera 9.5、IE7、FF3 和 Safari 中对此进行了测试,并且在所有这些版本中都可以使用。

    【讨论】:

    • 显然已经有一段时间了(大约 5.5 年),但值得注意的是您的链接已失效。
    • 这个解决方案对我不起作用。我在最新的 Firefox (45.0.1) 中遇到了这个问题
    【解决方案5】:

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

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

    【讨论】:

    • 单独的链接被认为是一个糟糕的答案(请参阅faq),因为它本身没有意义,并且不能保证目标资源在未来仍然存在It would be preferable 在这里包含答案的基本部分,并提供链接以供参考。
    【解决方案6】:

    卸载事件在 IE 9 上无法正常工作。我尝试使用加载事件 (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>
    

    【讨论】:

      【解决方案7】:

      我无法让上述示例正常工作。我只是想在通过后退按钮返回页面时触发某些修改过的 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>
      

      只要我点击后退按钮,它就会正确触发。

      【讨论】:

      • 虽然这在 Firefox 中不起作用,但我认为这是一种巧妙的方法来处理 IE/Chrome 中隐藏字段的持久性非常有用的情况。我已经使用了你的技巧以及“pageshow”事件,所以我涵盖了所有主要的浏览器。
      • 哪个浏览器不支持pageshow?
      【解决方案8】:

      我可以确认 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>
      

      【讨论】:

        【解决方案9】:

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

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

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

        【讨论】:

          【解决方案10】:

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

          【讨论】:

            【解决方案11】:

            各位,我发现JQuery只有一个作用:按下后退按钮时页面会重新加载。这与“ready”无关。

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

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

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

            [edit(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>
            

            【讨论】:

            • 非常好......虽然这是一个未记录的功能/错误,并且可能会在未来版本的浏览器中停止工作,但它仍然很有趣。
            • 这也可以(不要忘记 onunload="" 部分,否则在 ff3 上不起作用):
            • 这是因为如果页面有一个onunload 处理程序,浏览器就认为该页面是不可缓存的(页面已经销毁了所有内容;为什么要缓存它?)。
            • Answer 似乎在现代浏览器中不起作用 - 在最新的 Chrome 和 Opera 中检查
            • 它在 iPad safari 中不起作用...请取消将其标记为答案
            【解决方案12】:

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

            【讨论】:

              【解决方案13】:

              好的,我试过了,它在 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>
              

              【讨论】:

                【解决方案14】:

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

                【讨论】:

                  【解决方案15】:

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

                  【讨论】:

                  • 很久以后,ready 在 Firefox 中使用后退按钮时似乎没有被触发。另请参阅Nickolay's answer
                  猜你喜欢
                  • 1970-01-01
                  • 2014-10-30
                  • 1970-01-01
                  • 2014-11-06
                  • 2011-06-17
                  • 1970-01-01
                  相关资源
                  最近更新 更多