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

时间:2008-10-01 15:50:36

标签: javascript pageload

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

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

15 个答案:

答案 0 :(得分:111)

伙计们,我发现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>

答案 1 :(得分:72)

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

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

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

对于需要知道何时被导航/返回的页面,Firefox 1.5+和具有bug 28758修复程序的Safari版本支持称为“pageshow”和“pagehide”的特殊事件。 / p>

参考文献:

答案 2 :(得分:31)

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

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

以为我会分享我的发现,希望他们会帮助别人。

编辑完整性

我的代码如下:

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

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

答案 3 :(得分:21)

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

此页面有more information

示例:

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

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

答案 4 :(得分: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>

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

答案 5 :(得分:4)

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

答案 6 :(得分:4)

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

答案 7 :(得分:4)

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

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

答案 8 :(得分:4)

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

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

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

答案 9 :(得分:3)

jQuery's ready事件就是针对此类问题而创建的。您可能希望深入了解实现,以了解幕后发生的事情。

答案 10 :(得分:2)

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

答案 11 :(得分:2)

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

答案 12 :(得分: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>

答案 13 :(得分:1)

卸载事件在IE 9上运行不正常。我尝试使用load event(onload()),它在 IE 9 FF5 上工作正常。< / p>

示例:

<%@ 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>

答案 14 :(得分:0)

我已经使用了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