Firefox在选项卡恢复后触发onchange事件

4nt*_*nti 27 html javascript firefox html5

在恢复选项卡后,Firefox正在我的webapp中触发更改事件.

在Firefox中重新加载相同的URL时没有问题,在页面加载时不会触发onchange事件,自上次访问以来所有更改的值都会正确显示.

但是当重新打开具有相同URL的同一页面时,关闭Firefox并重新打开带有"恢复选项卡"的页面(来自Firefox选项"从上次显示我的窗口和选项卡")然后它会触发所有值的onchange事件自上次访问以来已被更改.

实际工作流程重现问题:

  1. 我的更新事件是在后台(JavaScript/AJAX),并使用onchange事件触发;
  2. Firefox设置"上次显示我的窗口和标签"启用;
  3. 更改页面中的一些值(选择字段);
  4. 关闭Firefox;
  5. 在另一台浏览器或计算机上打开相同的URL,并更改一些值;
  6. 重新打开Firefox,选择包含页面的选项卡,它会重新加载并在上次访问后为所有更改的值重新启动更改事件.

尝试使用完全不同的页面(不是由我创建并使用其他脚本库和东西)重现此行为,结果是相同的,它始终触发onchange事件.

Chrome没有使用"恢复标签"选项执行此操作.

为什么要开启onchange事件?我该怎样预防呢?

Jul*_*ire 2

根据想要的结果,提供一些关于如何处理此问题的建议。请注意,这是在我的机器上测试的,行为可能会有所不同。他们的工作方式似乎是 Firefox 尝试恢复用户输入的数据。因此它修改了页面,触发了change event. 该事件与用户触发的事件略有不同。这是一UIEvent会用户触发的一是直的Event。并且这个Event是cancelable在该事件之前触发的window load。因此,这提供了几种处理此问题的方法。我将以选择元素为例。

如果您希望 select 保留窗口关闭前输入的值,但不触发 onchange 事件,您可以在window.onload. 像这样:

window.onload = function(){
     element.onchange = function(){
Run Code Online (Sandbox Code Playgroud)

由于 的设置select发生在 之前onload,因此此特定更改不会触发您的onchange函数。

另一种方法是通过设置一个条件来验证元素是否可取消,从而定位您不触发的行为。如果是cancelable,则意味着它是从恢复会话中调用的,并且不会触发内部内容。像这样:

element.onchange = function(e){
         if(e.cancelable == true){
Run Code Online (Sandbox Code Playgroud)

另一种方式是,要清除所有数据,请设置一个document.onchange事件并在该事件为 时重新加载页面cancelable。像这样:

 document.onchange = function(e){
        if(e.cancelable == true){
            window.location = window.location
             }
      }
Run Code Online (Sandbox Code Playgroud)

当然,您需要确保页面中没有调用任何其他可取消的更改事件。

编辑:

要澄清事件触发的顺序,请参阅此 jsfiddle,而不是在 iframe 中,iframe 的行为似乎有所不同,因此如果您有 iframe,则可能会更复杂一些。但如果没有 iframe,您将看到如何根据您的交互触发不同的事件:

 document.onchange = function (e) {
      //this will be triggered on restore before the window load event           
      alert('restore onchange called, e.cancelable = ' + e.cancelable)
 }


 window.onload = function (e) {
     //You'll see that on restore, this will be triggered but after page has been updated
     alert('window load called')
     document.onchange = function () {
         //This onchange will be called normally, not on restore
         alert('after onload change, e.cancelable = ' + e.cancelable)
     }

 }
Run Code Online (Sandbox Code Playgroud)

http://fiddle.jshell.net/nozp9uhk/6/show/