jquery - window.onload 在 Firefox 中的 jQuery document.ready 之前触发

标签 jquery firefox jquery-events document-ready domcontentloaded

我创建了一个显示问题的 Codepen:https://codepen.io/samuelg0rd0n/pen/ExVGQEV

在 Chrome 中,它会在窗口 onload 事件之前正确触发 DOMContentLoaded 事件和 jQuery 文档就绪事件。但是,在 Firefox 中,顺序是:

DOMContentLoaded
window.onload
$(window).on('load', function() { ... });
$(document).ready();
$(function() { ... });

window.onload 和 jQuery window onLoad 在 jQuery 文档就绪事件之前被触发。我很确定这一定是 jQuery 或 Firefox 中的某种错误。谁可以给我解释一下这个?谢谢你。

Chrome 版本:81.0.4044.138

火狐版本:75.0

在 macOS 和 Linux 中都尝试过,结果相同。

最佳答案

这似乎是一个 jQuery 问题。我是这样测试的:

  • 当我使用 vanilla JS 函数时,我在 Firefox 中得到正确的顺序(首先触发 DOM Ready,然后是窗口加载):
     document.addEventListener('DOMContentLoaded', function(event) {
       console.log('DOMContentLoaded');
     }); 
     window.addEventListener('load', function(event) {
       console.log('window load');
     });
    
  • 当我使用 jQuery 时,我得到了错误的顺序(首先触发窗口加载,然后是 DOM Ready):
     $( window ).on( 'load', function() {
       console.log('window load');
     }); 
     $(function () {
       console.log('DOM Ready');
     }); 
    

  • 注意:这种错误的顺序只有在缓存资源和关闭 Web 控制台时才会发生。
    您可以通过运行以下代码来验证触发事件的正确顺序的相同方式:
    document.addEventListener('readystatechange', function(event) {
      console.log( 'readystatechange', document.readyState );
    });
    
    在 firefox 中,它总是首先触发“交互式”状态(例如 DOMContentLoaded)然后“完成”(例如窗口加载)。
    因此,它不是 DOMContentLoaded 事件在窗口加载事件之前触发,而是 jQuery 的 DOM 就绪事件处理程序出于某种原因在窗口加载事件之前触发。
    这是在 jQuery 版本 3.5.1 上测试的,这是最新的。在 Mac 上运行的 Firefox 版本 82.0.3(64 位)。
    现在,我通过添加一个标志变量并在 jQuery 的 DomReady 事件中检查它来使用一个简单的解决方法。如果在 jQuery 的 DOM Ready 事件触发时窗口已经加载,我会运行我的函数,这些函数必须再次在窗口加载时运行。它并不理想或优雅,但完全满足简单的网页脚本。
    var windowLoaded = false;
    $( window ).on( 'load', function() {
      windowLoaded = true;
      runMyWindowLoadFunctions();
    } );
    $(function() {
      if ( windowLoaded ) {
        // Beware, runMyWindowLoadFunctions will run twice
        runMyWindowLoadFunctions();
      }
    });
    
    更新
    刚刚检查了就绪事件的 jQuery 源代码 https://github.com/jquery/jquery/blob/master/src/core/ready.js
    // The ready event handler and self cleanup method
    function completed() {
      document.removeEventListener( "DOMContentLoaded", completed );
      window.removeEventListener( "load", completed );
      jQuery.ready();
    }
    
    // Catch cases where $(document).ready() is called
    // after the browser event has already occurred.
    if ( document.readyState !== "loading" ) {
    
      // Handle it asynchronously to allow scripts the opportunity to delay ready
      window.setTimeout( jQuery.ready );
    
    } else {
    
      // Use the handy event callback
      document.addEventListener( "DOMContentLoaded", completed );
    
      // A fallback to window.onload, that will always work
      window.addEventListener( "load", completed );
    }
    
    如您所见,可能会出现在处理 jQuery 脚本之前触发窗口加载事件的情况,在这种情况下,jQuery 正在运行“就绪”事件处理程序。
    据我了解,jQuery 不会在运行窗口加载事件处理程序之前检查其“就绪”事件处理程序是否已被触发。

    关于jquery - window.onload 在 Firefox 中的 jQuery document.ready 之前触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61910610/

    相关文章:

    javascript - 停止传播 jQuery 委托(delegate)/实时函数不起作用

    javascript - 在事件 anchor 上运行功能

    javascript - 获取对附加项目的引用并将一些其他项目附加到先前附加的项目

    javascript - JQuery - 更改 onchange 事件上划分行的颜色?

    javascript - 将列样式应用于表体元素

    python - 操作系统错误 : [Errno 8] Exec format error: 'geckodriver' when trying to open firefox using selenium in python

    javascript - Selenium Firefox 与 Python3 FirefoxProfile.set_preference() 被忽略

    javascript - 在 Chrome 和 Firefox 中关闭 https 门控 Web API 的 https 要求

    javascript - 如何使用 Firebug 或类似工具调试 JavaScript/jQuery 事件绑定(bind)?

    javascript - jScript 确认当字段脏时导航离开,多浏览器实现?