DOMContentLoaded事件是否与jQuery的.ready()函数完全相同?

时间:2012-07-17 13:17:50

标签: javascript jquery events dom javascript-events

我用jQuery的window.addEventListener('DOMContentLoaded', function() {});替换了$(document).bind('ready', function() {});,因为第一个无法在IE上工作< 9我不想和那个虚拟浏览器一起玩.attachEvent(),如果我可以用jQuery本身很好地覆盖它。

更换后不久,我注意到DOMContentLoaded事件总是在页面加载/刷新后大约0-2毫秒被触发(至少这是我的日志记录脚本所记录的),而.ready()总是{{1}}在页面刷新之后,需要至少15-20毫秒才能被触发(再次 - 由脚本记录)。

我纯粹是为了满足于我的好奇心,为什么会出现这种“显着”的延迟?当然,对我来说没有问题,jQuery稍后会触发该事件。只是,因为我想知道所有的答案(统治世界!:)),我无法忍受! :

编辑:在.ready() function doc某个用户(Nick(of Nexxar))指出:“ jQuery模拟IE上不存在的”DOMContentLoaded“事件,但是使用过的机制比其他浏览器上使用的事件要晚得多“。也许这是一样的,我要求的?

4 个答案:

答案 0 :(得分:21)

假设支持该事件的浏览器:

  1. 真实事件可以支持任何document。 jQuery只会使用它所加载的document,无论你传递给它。
  2. 即使事件已经发生,jQuery也会异步触发事件。如果事件已经发生,则附加'DOMContentLoaded'事件将不会执行任何操作。
  3. 这些浏览器没有延迟,请参阅http://jsfiddle.net/rqTAX/3/(记录的偏移量以毫秒为单位)。

    对于不支持该事件的浏览器,jQuery显然也适用于它们。它将使用与真实DOMContentLoaded不同的hacky机制,并且不会在真实DOMContentLoaded之后立即触发:

    // The DOM ready check for Internet Explorer
    function doScrollCheck() {
        if ( jQuery.isReady ) {
            return;
        }
    
        try {
            // If IE is used, use the trick by Diego Perini
            // http://javascript.nwbox.com/IEContentLoaded/
            document.documentElement.doScroll("left");
        } catch(e) {
            setTimeout( doScrollCheck, 1 );
            return;
        }
    
        // and execute any waiting functions
        jQuery.ready();
    }
    

答案 1 :(得分:4)

jQuery通过绑定document的{​​{1}}事件来模拟此事件,这是在oldIE中模拟readystatechange的标准方法。

According to the jQuery source,该事件在DOMContentLoaded之前“迟到”。但是,当事件正好触发时,我找不到。在构建DOM并准备好编写脚本时,window.onload会触发,因此DOMContentLoaded之后触发;也许它等待布局渲染或样式这样的事情,或者事件是在渲染/布局过程中稍后触发的?

无论如何,它可能会在 readystatechange之后触发,可能是由于IE决定将DOMContentLoaded的{​​{1}}更新为“完成”。< / p>

(如果有人有一个明确的答案,发表评论,我会更新这个答案;我很想知道它到底是什么时候开始,我在任何文件或任何网站上找不到答案我期待像Quirksmode。)

答案 2 :(得分:1)

准备好的另一个原因&#39;后来(实际上)似乎可能会发生许多事件。如果其中任何一个是长时间运行的同步操作,那么就绪事件将会更晚。例如,我使用knockout.js,初始化页面可能需要500ms。

然而,使用您的最小测试页面当然不是这样。我尝试运行以下内容:

 console.log(window.performance.timing.domContentLoadedEventEnd -
             window.performance.timing.domContentLoadedEventStart);

即使您的简单超级页面也提供约6ms

此外,我接受了您的代码并通过Chrome的性能工具运行它,并发现了一些有趣的事情:

enter image description here

  • 顺便说一句:垂直的蓝色条是DOMCONTENTLOADED,绿色是第一次涂漆&#39;
  • 您甚至可以看到DOMCONTENTLOADED事件上的超级简单函数调用可能需要5ms(这是在i7上)。请记住,需要对其进行解析,并且需要初始化。
  • 回调以青色(匿名)显示,第一个来自DOMCONTENTLOADED事件,第二个是&#39; ready&#39;回调。
  • 您会注意到&#39;定时器被点击&#39; (即setTimeout)。因此,它无论如何都不是即时的。

查看jQuery source code您看到他们实际上为回调设置了一个计时器:

// Handle it asynchronously to allow scripts the opportunity to delay ready
window.setTimeout( jQuery.ready );

确切地确定他们在这里的意思(任何想法) - 但它解释了行为。我可以看到它有助于避免竞争条件,并阻止用户界面,但延迟准备就绪&#39;我不清楚。

答案 3 :(得分:0)

除了我以外,还有人使用jQuery吗? ;)

jQuery 3.0 开始,仅推荐使用np.around语法,
(相当于$( handler ))。

来自API文档:.ready()