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

Is there a cross-browser onload event when clicking the back button?

本文关键字:浏览器 加载 事件 存在 是否 按钮 单击      更新时间:2023-09-26

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

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

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

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

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

默认情况下,它不执行任何操作。但不知何故,这似乎触发了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>

使用 JQuery 时,您将看到类似的结果。

您可能想在没有卸载的情况下与这个进行比较

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

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

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

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

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

引用:

  • 网络套件:http://webkit.org/blog/516/webkit-page-cache-ii-the-unload-event/
  • 火狐:https://developer.mozilla.org/En/Using_Firefox_1.5_caching。
  • 铬:https://code.google.com/p/chromium/issues/detail?id=2879

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

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

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

编辑完整性

我的代码如下所示:

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

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

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

此页面包含更多信息。

例:

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

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

我无法让上面的例子工作。我只是想在通过后退按钮返回页面时触发某些修改后的div 区域的刷新。我使用的技巧是在div 区域与原始区域更改后立即将隐藏输入字段(称为"脏位")设置为 1。当我单击返回时,隐藏的输入字段实际上保留了其值,因此我可以在加载时检查此位。如果已设置,我会刷新页面(或只是刷新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>

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

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

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

我认为这是针对"onunload",而不是页面加载,因为我们不是在谈论在点击"返回"时触发事件吗? $document.ready() 适用于页面加载时所需的事件,无论您如何到达该页面(即重定向、直接打开浏览器到 URL 等),而不是在单击"返回"时,除非您在谈论在再次加载时在上一页触发什么。 而且我不确定该页面是否被缓存,因为我发现 Javascript 仍然存在,即使其中包含 $document.ready() 也是如此。 在编辑脚本时,我们必须按 Ctrl+F5,每当我们修改它们时,这些脚本都会发生此事件,并且我们希望在页面中测试结果。

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

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

jQuery的ready事件就是为这类问题而创建的。 您可能想深入研究实现,看看幕后发生了什么。

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

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

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

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

好的,我试过这个,它适用于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>
卸载事件在

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>

我使用了html模板。在此模板的自定义.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

我正在构建一个基于 file:///协议的网站。(火狐 116.0.1 64 位)因此,这可能不适用于这里的许多情况:

但是,当我使用后退按钮到达一个包含运行页面所需的脚本的页面时,它会失败。 单击指向该页面的链接不会失败。

失败的定义:浏览器选项卡将锁定并变得无响应,需要关闭。浏览器的"后退"、"Forw"和"停止"按钮不可点击。

当我尝试onunload=""时,同样的失败随之而来......

但是,当我为 onunload OR 设置一个真正的函数并让它调用在 body 标签的 onload 属性中描述的函数时,开始重新加载所需的 javasript。

例:

<body onload="page_defaults()" onunload="back_button_reload_fix()>
function back_button_reload_fix(){
    page_defaults();
}