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

时间:2020-03-06 14:58:57  来源:igfitidea点击:

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

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

解决方案

jQuery的ready事件就是针对此类问题而创建的。我们可能需要深入研究实现,以了解幕后到底发生了什么。

比尔,我敢回答问题,但是我不确定我的猜测是100%。我认为,将用户带入历史页面时,其他IE浏览器不仅会从缓存中加载页面及其资源,还会为它恢复整个DOM(读取会话)状态。 IE不会进行DOM恢复(或者至少不会进行DOM恢复),因此onload事件对于在那里正确的页面重新初始化似乎是必需的。

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

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

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

此页面上有更多信息。

例子:

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

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

伙计们,我发现JQuery仅具有一种作用:当按下后退按钮时,页面将重新加载。这与"就绪"无关。

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

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

默认情况下,它不执行任何操作。但是无论事件处理程序包含什么内容,这似乎都可以在Safari,Opera和Mozilla中触发重新加载。

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

使用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>

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

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

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

这也是为什么添加"卸载"处理程序会使页面无法存储在bfcache中的原因(因此使其导航回去的速度变慢)-卸载处理程序可能会执行清理任务,这可能会使页面处于无法工作的状态。

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

参考:

  • Webkit:http://webkit.org/blog/516/webkit-page-cache-ii-the-unload-event/
  • Firefox:https://developer.mozilla.org/En/Using_Firefox_1.5_caching。
  • Chrome:https://code.google.com/p/chromium/issues/detail?id = 2879

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

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

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

编辑完整

我的代码如下所示:

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

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

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

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

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