Javascript DOMContentLoaded 事件是否与 jQuery 的 .ready() 函数完全相同?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11523359/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is DOMContentLoaded event EXACTLY the same as jQuery's .ready() function?
提问by trejder
I have replaced window.addEventListener('DOMContentLoaded', function() {});
with jQuery's $(document).bind('ready', function() {});
, because first one failed to work on IE < 9 and I did not wanted to play with .attachEvent()
for that dummy browser, if I could have this nicely covered by jQuery itself.
我已经window.addEventListener('DOMContentLoaded', function() {});
用 jQuery替换了$(document).bind('ready', function() {});
,因为第一个无法在 IE < 9 上工作,而且我不想.attachEvent()
为那个虚拟浏览器玩,如果我可以用 jQuery 本身很好地覆盖它。
Shortly after replacement, I noticed that DOMContentLoaded
event was always fired around 0-2 miliseconds after page load / refresh (at least this is what was logged by my logging script), while .ready()
always requires at least 15-20 miliseconds, after page refresh, to be fired (again - as logged by script).
替换后不久,我注意到DOMContentLoaded
在页面加载/刷新后总是在 0-2 毫秒左右触发事件(至少这是我的日志记录脚本记录的内容),而.ready()
在页面刷新后总是需要至少 15-20 毫秒被解雇(再次 - 由脚本记录)。
I'm asking purely for feeding my curiosity, why there is such "significant" delay? Of course, there is no problem for me, that jQuery is firing that event later. It is just, that because I want to know ALL the answers (and rule the world! :]), I can't sleep with that! :]
我纯粹是为了满足我的好奇心,为什么会有如此“显着”的延迟?当然,对我来说没有问题,jQuery 稍后会触发该事件。只是,因为我想知道所有答案(并统治世界!:]),所以我睡不着!:]
EDIT: in .ready() function docsome user (Nick (of Nexxar)) points out that: "jQuery simulates the non existing "DOMContentLoaded" event on IE, but the used mechanism fires much later than the event used on other browsers". Maybe this is the same, I'm asking for?
编辑:在.ready() 函数文档中,一些用户(尼克(Nexxar))指出:“ jQuery 在 IE 上模拟了不存在的“DOMContentLoaded”事件,但使用的机制比其他浏览器上使用的事件晚得多“ . 也许这是一样的,我要求?
采纳答案by Esailija
Assuming browser that supports the event:
假设浏览器支持该事件:
- The real event can support any
document
. jQuery will only use thedocument
it was loaded in, no matter what you pass to it. - jQuery will fire the event asynchronously even if the event has already happened. Attaching
'DOMContentLoaded'
event will do nothing if the event has already happened.
- 真实事件可以支持任何
document
.document
无论您传递给它什么,jQuery 都只会使用它被加载的那个。 - 即使事件已经发生,jQuery 也会异步触发事件。
'DOMContentLoaded'
如果事件已经发生,附加事件将不起作用。
There is no delay in these browsers, see http://jsfiddle.net/rqTAX/3/(the offsets logged are in milliseconds).
这些浏览器没有延迟,请参阅http://jsfiddle.net/rqTAX/3/(记录的偏移量以毫秒为单位)。
For browsers that don't support the event, jQuery's will obviously work for them as well. It will use a hacky mechanism that is not the same as the real DOMContentLoaded
and will not necessarily fire as soon as the real DOMContentLoaded
would:
对于不支持该事件的浏览器,jQuery 显然也适用于它们。它将使用与真实不同的hacky机制,DOMContentLoaded
并且不一定会像真实那样立即触发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();
}
回答by ajm
jQuery simulates this event by binding to the document
's readystatechange
event, which is the standard way of simulating DOMContentLoaded
in oldIE.
jQuery的通过结合到模拟了这种事件document
的readystatechange
事件,这是模拟的标准方式DOMContentLoaded
中过时的歌曲。
According to the jQuery source, that event fires "late" but before window.onload
. However, I can't find whenthat event fires exactly. DOMContentLoaded
fires when the DOM is built and ready for scripting, so readystatechange
fires afterthat; perhaps it waits for layout rendering or styling something like that, or the event is triggered later in the rendering/layout process?
根据 jQuery 来源,该事件在window.onload
. 但是,我无法找到时该事件触发准确。DOMContentLoaded
在构建 DOM 并准备好编写脚本时readystatechange
触发,因此在此之后触发;也许它等待布局渲染或样式类似的东西,或者事件在渲染/布局过程中稍后触发?
Regardless, it will likely fire afterDOMContentLoaded
, likely due to when IE decides to update the document
's readyState
to "complete."
无论如何,它可能会在 之后触发DOMContentLoaded
,这可能是由于 IE 决定将document
's更新readyState
为“完成”。
(If anyone has a definite answer, post a comment and I'll update this answer; I'd love to know when exactly it fires myself, and I can't find that answer in any documentation or on any sites I would expect like Quirksmode.)
(如果有人有明确的答案,请发表评论,我会更新此答案;我很想知道它何时触发自己,我在任何文档或我希望的任何网站上都找不到该答案怪癖模式。)
回答by Simon_Weaver
Another reason for the 'ready' appearing to fire later (in practice) is that there may be many events hooked up to it. If any of these are long running synchronous operations then the ready event will come much later. For instance I use knockout.js and it can take 500ms to initialize the page.
'ready' 出现在稍后(在实践中)的另一个原因是可能有许多事件与之相关。如果其中任何一个是长时间运行的同步操作,那么就绪事件将在很晚之后出现。例如,我使用knockout.js 初始化页面可能需要500 毫秒。
However using your minimal test page that isn't the case of course. I tried running the following :
但是,使用您的最小测试页面当然不是这种情况。我尝试运行以下命令:
console.log(window.performance.timing.domContentLoadedEventEnd -
window.performance.timing.domContentLoadedEventStart);
This gives about 6ms even for your simple super page
即使对于您的简单超级页面,这也提供了大约 6 毫秒的时间
Also I took your code and ran it through Chrome's performance tools and discovered a few interesting things:
我还使用了您的代码并通过 Chrome 的性能工具运行它,并发现了一些有趣的事情:
- BTW: The vertical blue bar is DOMCONTENTLOADED and the green is 'first paint'
- You can see even just a super simple function call on the DOMCONTENTLOADED event can take 5ms (and this is on an i7). Remember it needs to be parsed and things need initializing.
- The callbacks are shown in the cyan color (anonymous), the first is from the DOMCONTENTLOADED event and the second is the 'ready' callback.
- You will notice 'Timer Fired' (i.e.
setTimeout
). So it is not instantaneous at by any means.
- 顺便说一句:垂直的蓝色条是 DOMCONTENTLOADED,绿色是“第一次绘制”
- 您可以看到,即使是对 DOMCONTENTLOADED 事件的超级简单函数调用也可能需要 5 毫秒(这是在 i7 上)。记住它需要被解析并且需要初始化。
- 回调以青色(匿名)显示,第一个来自 DOMCONTENTLOADED 事件,第二个是“就绪”回调。
- 您会注意到“计时器已触发”(即
setTimeout
)。所以它无论如何都不是瞬间的。
Looking at the jQuery source codeyou see they actually set a timer for the callbacks:
查看jQuery 源代码,您会发现它们实际上为回调设置了一个计时器:
// Handle it asynchronously to allow scripts the opportunity to delay ready
window.setTimeout( jQuery.ready );
I'm not exactlysure what they mean here (any idea) - but it explains the behavior. I could see it being helpful to avoid race conditions, and blocking the UI but 'delaying ready' is unclear to me.
我并不确切地知道什么他们的意思在这里(任何想法) -但它说明了其行为。我可以看到避免竞争条件和阻止 UI 很有帮助,但我不清楚“延迟准备”。