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


185

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

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


6
这不是问题-当用户按下“后退”按钮时,它可以快速加载网页。请参阅下面的详细信息。由于向后/向前导航较慢,因此此处建议的解决方法使网页更让用户烦恼。
Nickolay 2010年

2
@romkyns:您的评论与此问题无关。当浏览器不还原JS / DOM状态时,它们会触发load事件。
Nickolay'5

iOS 5+历史后退按钮已在此处解决stackoverflow.com/a/12652160/1090395
Mladen Janjetovic

Answers:


117

伙计们,我发现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
很好。虽然这是一个未记录的功能/错误,并且可能会在以后的浏览器版本中停止工作,但是仍然很有趣。
Wadih M.

3
这也很好(别忘了onunload =“”部分,否则在ff3上不起作用):<body onload =“ alert('onload');” onunload =“”>
Wadih M.

3
这是因为浏览器假定该页面具有onunload处理程序(该页面已经销毁了所有内容;为什么要缓存它?),因此该页面不可缓存。
Casey Chu

14
答案似乎并不在现代浏览器的工作-在最新的检查Chrome和Opera
安德鲁·

10
它在iPad Safari浏览器中不起作用...请取消此标记为答案
xus

74

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

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

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

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

参考文献:


太酷了。我目前的情况是我的dom操纵似乎没有保存在bfcache中。在任何情况下您可能会期望吗?
本森

1
@Benson:我链接到的dev.mo页面上列出了Firefox无法将页面保存在bfcache中的可能原因。我认为不可能将页面保存到bfcache,但是某些DOM状态无法保存。
Nickolay 2010年

Nickolay,我不愿强制重新加载并撤消bfcache完成的出色工作,但是还有另一种方法可以更新bfcache中的页面dom吗?例如,考虑以下情况:我从具有消息列表的页面转到其中一个消息,当我“返回”时,我希望已读/未读指示器发生变化。如何在不重新加载页面的情况下完成此操作?
格雷格,2010年

@Greg:您的意思是作为控制页面的开发人员?触发来自“ pageshow”监听器的ajax请求。
Nickolay 2010年

关于如何使用jQuery并获得快速bfcache支持的任何想法吗?
亚历克斯·布莱克

31

我遇到一个问题,当用户单击后退或前进时,我的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中。


7
您在哪里添加的?在用户反击之后,您是如何得到触发的?请给我们看一些代码!
Keerigan

说“我的条件陈述”是什么意思?
菲利普·森

1
@Phillip条件语句是if语句。
Brian Heese 2015年

22

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

此页面有更多信息

例:

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

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


2
显然已经有一段时间了(大约5.5年),但是值得注意的是您的链接已死。
杰夫

2
此解决方案不适用于我。我有这个问题在最新的Firefox(45.0.1)
阿明

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>

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


3
尽管这在Firefox中不起作用,但我认为这是处理IE / Chrome中隐藏字段的持久性非常有用的一种巧妙方法。我已经使用了您的技巧以及“ pageshow”事件,因此涵盖了所有主要的浏览器。
Magnus Smith

哪种浏览器不支持页面显示?
贾斯汀

4

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


4

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

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

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


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>

4

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

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


1
孤独的链接被认为是一个不好的答案(请参阅常见问题解答),因为它本身没有任何意义,并且不能保证目标资源在将来仍然有效最好在此处包括答案的基本部分,并提供链接以供参考。
j0k


2

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


2

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


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>

1

卸载事件在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>

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.