DOMContentLoaded和load事件之间的区别是什么?


来自Mozilla开发者中心:

DOMContentLoaded事件在文档被删除时被触发 完全加载和解析,无需等待样式表,图像, 和子帧完成加载(load事件可以用来检测 一个完整的页面)。


DOMContentLoaded事件将在DOM层次结构完全构建完成后立即触发,load事件将在所有图像和子帧完成加载时触发。

DOMContentLoaded可以在大多数现代浏览器上运行,但不能在IE上运行,包括IE9及以上版本。在旧版本的IE上有一些变通方法来模拟这个事件,比如jQuery库上使用的,它们附加了IE特定的onreadystatechange事件。


DOMContentLoaded = window . onDomReady ()

负荷= = window ()

在文档“准备好”之前,页面不能被安全操作,jQuery为您检测这种准备就绪状态。$(document).ready()中包含的代码只在页面文档对象模型(DOM)准备好执行JavaScript代码时才会运行。包含在$(window).load(function(){…})将在整个页面(图像或iframes),而不仅仅是DOM准备好后运行。

参见:使用JQuery Core的文档就绪文档。


你自己看看不同之处:

DEMO

来自微软IE

DOMContentLoaded事件在当前页面解析完成时触发;当所有文件完成从所有资源(包括广告和图像)加载时,load事件将触发。DOMContentLoaded是一个用于将UI功能连接到复杂网页的伟大事件。

来自Mozilla开发者网络

DOMContentLoaded事件在文档完全加载和解析时触发,而不需要等待样式表、图像和子帧完成加载(load事件可用于检测完全加载的页面)。


domContentLoaded: marks the point when both the DOM is ready and there are no stylesheets that are blocking JavaScript execution - meaning we can now (potentially) construct the render tree. Many JavaScript frameworks wait for this event before they start executing their own logic. For this reason the browser captures the EventStart and EventEnd timestamps to allow us to track how long this execution took. loadEvent: as a final step in every page load the browser fires an “onload” event which can trigger additional application logic.


下面是一些适用于我们的代码。我们发现MSIE在使用DomContentLoaded时会出现一些错误,当没有额外的资源被缓存时似乎会有一些延迟(根据我们的控制台日志,最高可达300ms),并且当它们被缓存时触发得太快了。所以我们采取了MISE的退路。不管DomContentLoaded是在外部JS文件之前还是之后触发doStuff()函数。

// detect MSIE 9,10,11, but not Edge
ua=navigator.userAgent.toLowerCase();isIE=/msie/.test(ua);

function doStuff(){
    //
}
if(isIE){
    // play it safe, very few users, exec ur JS when all resources are loaded
    window.onload=function(){doStuff();}
} else {
    // add event listener to trigger your function when DOMContentLoaded
    if(document.readyState==='loading'){
        document.addEventListener('DOMContentLoaded',doStuff);
    } else {
        // DOMContentLoaded already loaded, so better trigger your function
        doStuff();
    }
}

赞同人数最多的答案是错误的,至少在更高版本的Chrome 80+中是这样。

1、DOMContentLoaded不会触发,直到CSS和JavaScript被执行,DOM被解析(文档已经加载)

2、窗户。onload事件,该事件在所有网络资源(如CSS和JavaScript)加载完成、DOM解析完成(文档加载完成)之前不会触发。


基于Chrome 80+测试结果:

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>DOMContentLoaded , load</title> <link href="http://localhost/public/css?sleep=5000" rel="stylesheet"> <!-- 5000 milliseconds after the URL request the server begins to respond --> </head> <body> <img src="http://localhost/public/img?sleep=8000"> <!-- 8000 milliseconds after the URL request the server starts responding to the resource --> <script> document.addEventListener('DOMContentLoaded', () => { console.log('DOMContentLoaded OKOK') }) window.addEventListener('load', () => { console.log('window load OK') }) </script> <script src="http://localhost/public/js?sleep=2000"></script> <!-- 2000 milliseconds after the URL request the server begins to respond --> </body> </html>

测试执行结果: 页面运行5秒后,执行console.log('domContentLoaded OKOK')

console.log(' Window Load OK')在8秒后开始运行


为了充分理解,我建议阅读以下文章:

什么是DOM和CSSOM: https://developers.google.com/web/fundamentals/performance/critical-rendering-path/constructing-the-object-model 渲染树是什么:https://developers.google.com/web/fundamentals/performance/critical-rendering-path/render-tree-construction 所有与DOMContentLoaded、load和第一次打印相关的内容是怎样的: https://developers.google.com/web/fundamentals/performance/critical-rendering-path/analyzing-crp

简而言之:

DOMContentLoaded事件是在创建DOM时触发的(更多DOM是什么,请参阅链接1),load事件是在加载DOM、CSSOM和所有其他资源时触发的。如果你没有Javascript,那么你的网页加载的顺序可能是这样的:

或者用检查窗口的话来说,DOMContentLoaded事件将比load事件更早被触发(蓝线表示DOMContentLoaded,红线表示load事件):

然而,如果你使用Javascript(不是异步或延迟),那么DOM创建将等待JS加载。因为JS也会修改CSS,所以JS会等待CSSOM加载。

由于这是最常见的情况,因此在大多数场景中,DOMContentLoaded事件的创建实际上必须等待样式表也被加载。

加载链看起来像这样:

因此,DOMContentLoaded和load之间的主要区别是,在这种情况下,只有图像的加载时间,它可以与样式表和JS并行下载。

注意,如果你在JS中使用async或defer,就不会发生这种情况: