【问题标题】:Javascript load vs ready vs domready vs DOMContentLoaded eventsJavascript load vs ready vs domready vs DOMContentLoaded 事件
【发布时间】:2014-02-07 21:18:49
【问题描述】:

我有点迷失在“启动” 事件中 - 有很多不同的事件,并且在 DOM 和各种框架(如 jQuery)中命名不同。什么是所有可能的启动事件?它们有何不同?您能否展示一个简单的时间线来演示这些事件的触发顺序?

【问题讨论】:

    标签: javascript


    【解决方案1】:

    .ready()

    虽然 JavaScript 提供了用于执行代码的加载事件,但当 页面被渲染,直到所有资产都不会触发此事件 如图像已完全接收。在大多数情况下, 一旦 DOM 层次结构已完全运行,脚本就可以运行 建。传递给 .ready() 的处理程序保证是 在 DOM 准备好之后执行,所以这通常是最好的地方 附加所有其他事件处理程序并运行其他 jQuery 代码。使用时 依赖 CSS 样式属性值的脚本,这很重要 在之前引用外部样式表或嵌入样式元素 引用脚本。

    如果代码依赖于加载的资源(例如,如果 图像的尺寸是必需的),代码应放在 而是加载事件的处理程序。

    .ready() 方法通常与属性不兼容。如果必须使用负载,要么不要使用 .ready() 或使用 jQuery 的 .load() 方法将加载事件处理程序附加到 窗口或更具体的项目,如图像。

    参考:http://api.jquery.com/ready/

    .load()

    此方法是 .on( "load", handler ) 的快捷方式。

    当一个元素和所有子元素都有 已完全加载。此事件可以发送到任何元素 与 URL 关联:图像、脚本、框架、iframe 和 窗口对象。

    一般情况下,不必等待所有图像都完全 加载。如果代码可以更早执行,通常最好放置 它在发送到 .ready() 方法的处理程序中。

    参考:http://api.jquery.com/load-event/

    GlobalEventHandlers.onload

    加载事件在文档加载过程结束时触发。在 此时,文档中的所有对象都在 DOM 中,并且所有 图像和子帧已完成加载。

    还有 Gecko 特定的 DOM 事件,例如 DOMContentLoaded 和 DOMFrameContentLoaded(可以使用 EventTarget.addEventListener()) 在 DOM 之后触发 页面已构建,但不等待其他资源 完成加载。

    跨浏览器回退

    Internet Explorer 8 支持 readystatechange 事件,它可以是 用于检测 DOM 是否准备就绪。在 Internet 的早期版本中 Explorer,这个状态可以通过定期尝试执行来检测 document.documentElement.doScroll("left");,因为这个 sn-p 将抛出 在 DOM 准备好之前出现错误。

    jQuery 等通用 JS 库提供跨浏览器 方法来检测 DOM 是否准备就绪。还有独立的 提供此功能的脚本:contentloaded.js(仅支持一个 监听器)和 jquery.documentReady.js(不依赖于 jQuery, 尽管它的名字)。参考: https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers.onload

    代码:

    document.addEventListener("DOMContentLoaded", function (event) {
        console.log("DOM fully loaded and parsed");
    });
    
    function load() {
        console.log("load event detected!");
    }
    window.onload = load;
    
    $(document).ready(function () {
        console.log('ready');
    });
    
    $(window).load(function () {
        console.log('loaded');
    });
    

    时间线演示:http://jsfiddle.net/HgJ33/

    【讨论】:

      【解决方案2】:

      写下不同的框架及其事件可能会很有趣:

      这是使用 jsFiddle 的测试系列。相同的html,不同的框架,ms的区别。

      Mootools

      window.onload = function () {
          var now = new Date().getTime() - time;
          console.log(now, 'onload')             // 14 ms
      };
      window.addEvent('load', function () {
          var now = new Date().getTime() - time;
          console.log(now, 'load')               // 15 ms
      });
      window.addEvent('domready', function () {
          var now = new Date().getTime() - time;
          console.log(now, 'domready')           // 1 ms
      });
      

      jQuery

      window.onload = function () {
          var now = new Date().getTime() - time;
          console.log(now, 'onload')             // 20 ms
      };
      $(document).on('DOMContentLoaded', function () {
          var now = new Date().getTime() - time;
          console.log(now, 'DOMContentLoaded')   // 10 ms
      });
      $(document).on('ready', function () {
          var now = new Date().getTime() - time;
          console.log(now, 'ready')              // 20 ms
      });
      

      道场工具包

      dojo.addOnLoad(function() {
          //do stuff
      });
      

      YUI

      YUI().use('*',function(Y) {
          Y.on("domready", function() {
              //do stuff
          }, Y, "The DOMContentLoaded event fired.  The DOM is now safe to modify via script.");
      });
      

      原型

      document.observe("dom:loaded", function() { 
          //do stuff
      });
      

      煎茶JS

      Ext.onReady(function() {
          //do stuff
      });
      

      【讨论】:

      • 感谢毫秒,但我更愿意理解原理 - 如果事件基本上相同或不同,以及何时 它们是根据文档中的真实事件触发的。
      【解决方案3】:

      最好从你想要什么以及支持哪些浏览器的角度来思考。

      要在文档对象模型 (DOM) 中进行操作,您必须确保 HTML 页面通过网络加载并解析为树。解决这个问题的一种方法是在 HTML 文件的末尾编写所有代码,这导致只有在解析 HTML 之后才处理这些 javascript。另一种较新的标准方法是侦听 DOMReady 或 DOMContentLoaded 事件或 ready 事件,以确保仅在 DOM ready

      之后运行处理程序

      DOM 树构建完成后,浏览器将请求图像、音频、视频等。所有这些资源加载完毕后,窗口 load 事件被触发,现在页面已准备好完全呈现。

      所以基本上你应该只考虑你的代码是否可以在准备好 DOM 树的情况下执行,或者你是否需要加载所有内容才能运行你的代码。如果 DOM ready 的原生 javascript 实现没有涵盖您需要支持的所有浏览器,您可以选择 jQuery DOMready,这就是它制作的原因。

      【讨论】:

        【解决方案4】:

        总的来说,以前的答案非常好和完整。 但是 .ready() 和 DOMContentLoaded 事件之间存在一个重要区别。

        大多数浏览器都以 DOMContentLoaded 事件。然而,jQuery 的 .ready() 方法在 一个重要且有用的方法:如果 DOM 准备好并且浏览器 在代码调用 .ready(handler) 之前触发 DOMContentLoaded, 函数处理程序仍将被执行。相比之下,一个 事件触发后添加的 DOMContentLoaded 事件监听器永远不会 执行。

        参考。 https://api.jquery.com/ready/

        从这里我们可以看出,.ready() 在所有情况下都至少执行一次

        例如,在浏览器控制台中我们可以定义

        >> function sample()
        {
          console.log('This is sample.');
        
          $( document ).ready(function ()
          {
            console.log("Ready is working in all cases.")
          });  
        }
        undefined
        

        结果我们有

        >> sample();
        undefined
        This is sample. debugger eval code:3:11
        Ready is working in all cases. debugger eval code:7:13
        >> sample();
        undefined
        This is sample. debugger eval code:3:11
        Ready is working in all cases. debugger eval code:7:13
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-09-17
          • 1970-01-01
          • 2017-01-19
          • 2014-03-11
          • 2018-09-18
          • 1970-01-01
          • 2019-05-29
          相关资源
          最近更新 更多