Javascript 加载 vs 就绪 vs domready vs DOMContentLoaded 事件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21204612/
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
Javascript load vs ready vs domready vs DOMContentLoaded events
提问by TMS
I am a bit lost in the "start up"events - there are so many different events and are named differently in the DOM and in various frameworks like jQuery. What are all possible start up events? How do they differ? Can you show a simple timeline to demonstrate in which order are these events fired?
我有点迷失在“启动”事件中 - 有很多不同的事件,并且在 DOM 和各种框架(如 jQuery)中的命名也不同。什么是所有可能的启动事件?它们有何不同?您能否展示一个简单的时间线来演示这些事件的触发顺序?
回答by Irvin Dominin
.ready()
。准备好()
While JavaScript provides the load event for executing code when a page is rendered, this event does not get triggered until all assets such as images have been completely received. In most cases, the script can be run as soon as the DOM hierarchy has been fully constructed. The handler passed to .ready() is guaranteed to be executed after the DOM is ready, so this is usually the best place to attach all other event handlers and run other jQuery code. When using scripts that rely on the value of CSS style properties, it's important to reference external stylesheets or embed style elements before referencing the scripts.
In cases where code relies on loaded assets (for example, if the dimensions of an image are required), the code should be placed in a handler for the load event instead.
The .ready() method is generally incompatible with the attribute. If load must be used, either do not use .ready() or use jQuery's .load() method to attach load event handlers to the window or to more specific items, like images.
虽然 JavaScript 提供了用于在呈现页面时执行代码的 load 事件,但在完全接收到所有资产(例如图像)之前不会触发此事件。在大多数情况下,只要完全构建了 DOM 层次结构,就可以运行脚本。传递给 .ready() 的处理程序保证在 DOM 准备好后执行,因此这通常是附加所有其他事件处理程序和运行其他 jQuery 代码的最佳位置。使用依赖于 CSS 样式属性值的脚本时,在引用脚本之前引用外部样式表或嵌入样式元素非常重要。
如果代码依赖于加载的资产(例如,如果需要图像的尺寸),则应将代码放置在加载事件的处理程序中。
.ready() 方法通常与属性不兼容。如果必须使用 load,请不要使用 .ready() 或使用 jQuery 的 .load() 方法将加载事件处理程序附加到窗口或更具体的项目,如图像。
Ref: http://api.jquery.com/ready/
参考:http: //api.jquery.com/ready/
.load()
。加载()
This method is a shortcut for .on( "load", handler ).
The load event is sent to an element when it and all sub-elements have been completely loaded. This event can be sent to any element associated with a URL: images, scripts, frames, iframes, and the window object.
In general, it is not necessary to wait for all images to be fully loaded. If code can be executed earlier, it is usually best to place it in a handler sent to the .ready() method.
此方法是 .on( "load", handler ) 的快捷方式。
当一个元素和所有子元素都被完全加载时,加载事件被发送到一个元素。此事件可以发送到与 URL 关联的任何元素:图像、脚本、框架、iframe 和 window 对象。
一般来说,没有必要等待所有图像完全加载。如果代码可以更早地执行,通常最好将它放在发送到 .ready() 方法的处理程序中。
Ref: http://api.jquery.com/load-event/
参考:http: //api.jquery.com/load-event/
GlobalEventHandlers.onload
GlobalEventHandlers.onload
The load event fires at the end of the document loading process. At this point, all of the objects in the document are in the DOM, and all the images and sub-frames have finished loading.
There are also Gecko-Specific DOM Events like DOMContentLoaded and DOMFrameContentLoaded (which can be handled using EventTarget.addEventListener()) which are fired after the DOM for the page has been constructed, but do not wait for other resources to finish loading.
Cross-browser fallback
Internet Explorer 8 supports the readystatechange event, which can be used to detect that the DOM is ready. In earlier version of Internet Explorer, this state can be detected by regularily trying to execute document.documentElement.doScroll("left");, as this snippet will throw an error until the DOM is ready.
General-purpose JS libraries such as jQuery offer cross-browser methods to detect that the DOM is ready. There are also standalone scripts that offer this feature : contentloaded.js (supports only one listener) and jquery.documentReady.js (doesn't depend on jQuery, despite its name). Ref: https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers.onload
load 事件在文档加载过程结束时触发。至此,文档中的所有对象都在DOM中,所有的图片和子框架都已经加载完毕。
还有一些特定于 Gecko 的 DOM 事件,如 DOMContentLoaded 和 DOMFrameContentLoaded(可以使用 EventTarget.addEventListener() 处理),它们会在页面的 DOM 构建后触发,但不会等待其他资源完成加载。
跨浏览器回退
Internet Explorer 8 支持 readystatechange 事件,该事件可用于检测 DOM 是否已就绪。在较早版本的 Internet Explorer 中,可以通过定期尝试执行 document.documentElement.doScroll("left"); 来检测此状态,因为此代码段将引发错误,直到 DOM 准备就绪。
jQuery 等通用 JS 库提供了跨浏览器方法来检测 DOM 是否准备就绪。还有提供此功能的独立脚本:contentloaded.js(仅支持一个侦听器)和 jquery.documentReady.js(不依赖于 jQuery,尽管它的名称)。参考:https: //developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers.onload
Code:
代码:
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');
});
Timeline demo: http://jsfiddle.net/HgJ33/
时间线演示:http: //jsfiddle.net/HgJ33/
回答by Sergio
Can be interesting to write down the different frameworks and their events:
写下不同的框架及其事件会很有趣:
Here is test series using jsFiddle. Same html, different frameworks, difference in ms
.
这是使用 jsFiddle 的测试系列。相同的 html,不同的框架,不同的ms
.
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
});
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 Toolkit
道场工具包
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.");
});
Prototype
原型
document.observe("dom:loaded", function() {
//do stuff
});
Sencha JS
煎茶JS
Ext.onReady(function() {
//do stuff
});
回答by sabithpocker
It is better to think from the perspective of what you want and which browsers to support.
最好从您想要什么以及支持哪些浏览器的角度来考虑。
To make manipulations in Document Object Model (DOM) you will have to make sure the HTML page is loaded over network and parsed into a tree. One way of tackling this is by writing all code at end of the HTML file which leads to processing those javascript only after parsing the HTML. The other newer standard way is to listen for the DOMReady or DOMContentLoaded event or ready event to make sure the handler is run only after DOM is ready
要在文档对象模型 (DOM) 中进行操作,您必须确保 HTML 页面通过网络加载并解析为树。解决这个问题的一种方法是在 HTML 文件的末尾编写所有代码,这导致只有在解析 HTML 之后才能处理这些 javascript。另一种较新的标准方法是侦听 DOMReady 或 DOMContentLoaded 事件或准备好事件,以确保仅在 DOM准备好后才运行处理程序
After DOM tree is built browser will request for images, audio, video etc. After all these resources are loaded window loadevent is fired ,now the page is ready to be rendered fully.
DOM 树构建完成后,浏览器将请求图像、音频、视频等。在所有这些资源加载后,窗口加载事件被触发,现在页面已准备好完全呈现。
So basically you should just think if your code can be executed with the DOM tree ready, or do you need everything loaded to run your code. If the native javascript implementation of DOM ready doesnt cover all the browsers you need to support, you can go for jQuery DOMready that is the reason why its made.
所以基本上你应该考虑一下你的代码是否可以在 DOM 树准备好的情况下执行,或者你是否需要加载所有东西来运行你的代码。如果 DOM ready 的本机 javascript 实现没有涵盖您需要支持的所有浏览器,您可以选择 jQuery DOMready,这就是它制作的原因。
回答by ScienceKitten
In general, previosus answers are very good and full. But one important difference between .ready() and DOMContentLoaded event exists.
总的来说,previosus 的答案非常好且完整。但是 .ready() 和 DOMContentLoaded 事件之间存在一个重要区别。
Most browsers provide similar functionality in the form of a DOMContentLoaded event. However, jQuery's .ready() method differs in an important and useful way: If the DOM becomes ready and the browser fires DOMContentLoaded before the code calls .ready( handler ), the function handler will still be executed. In contrast, a DOMContentLoaded event listener added after the event fires is never executed.
大多数浏览器都以 DOMContentLoaded 事件的形式提供类似的功能。但是,jQuery 的 .ready() 方法在一个重要且有用的方面有所不同:如果 DOM 准备就绪并且浏览器在代码调用 .ready( handler ) 之前触发 DOMContentLoaded,则函数处理程序仍将被执行。相比之下,在事件触发后添加的 DOMContentLoaded 事件侦听器永远不会执行。
Ref. https://api.jquery.com/ready/
参考 https://api.jquery.com/ready/
As we see from this, .ready() is executed at least once in all cases.
从中我们可以看出,.ready() 在所有情况下都至少执行一次。
For example, in browser console we may define
例如,在浏览器控制台中,我们可以定义
>> function sample()
{
console.log('This is sample.');
$( document ).ready(function ()
{
console.log("Ready is working in all cases.")
});
}
undefined
and in result we have
结果我们有
>> 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