繁体   English   中英

DOMContentLoaded 和 load 事件的区别

[英]Difference between DOMContentLoaded and load events

DOMContentLoadedload事件有什么区别?

来自Mozilla 开发者中心

DOMContentLoaded 事件在文档完全加载和解析后触发,无需等待样式表、图像和子框架完成加载(加载事件可用于检测完全加载的页面)。

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

DOMContentLoaded适用于大多数现代浏览器, 但不适用于 IE, 包括 IE9 及更高版本。 有一些变通方法可以在旧版本的 IE 上模拟此事件,例如在 jQuery 库中使用的方法,它们会附加IE 特定的onreadystatechange事件。

自己看看区别:

演示

来自微软 IE

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

来自Mozilla 开发者网络

DOMContentLoaded 事件在文档完全加载和解析后触发,无需等待样式表、图像和子框架完成加载(加载事件可用于检测完全加载的页面)。

DOMContentLoaded == window.onDomReady()

Load == window.onLoad()

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

请参阅:使用 JQuery Core 的文档就绪文档

  • domContentLoaded :标记 DOM 准备就绪并且没有样式表阻止 JavaScript 执行的时间点——这意味着我们现在可以(可能)构建渲染树。 许多 JavaScript 框架在开始执行自己的逻辑之前会等待此事件。 出于这个原因,浏览器会捕获 EventStart 和 EventEnd 时间戳,以允许我们跟踪此执行所花费的时间。

  • loadEvent :作为每个页面加载的最后一步,浏览器会触发“onload”事件,该事件可以触发额外的应用程序逻辑。

来源

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

  1. 什么是 DOM 和 CSSOM: https : //developers.google.com/web/fundamentals/performance/critical-rendering-path/constructing-the-object-model
  2. 什么是渲染树: https : //developers.google.com/web/fundamentals/performance/critical-rendering-path/render-tree-construction
  3. 与 DOMContentLoaded、加载和首次打印有什么关系: https : //developers.google.com/web/fundamentals/performance/critical-rendering-path/analyzing-crp

简而言之

DOMContentLoaded事件在创建DOM时触发(有关DOM更多信息,请参见链接 1),并且在load DOMCSSOM和所有其他资源时触发load事件。 如果您没有 Javascript,那么您的网页加载顺序可能如下所示: 在此处输入图片说明

或者用检查窗口的话来说, DOMContentLoaded事件会比load事件更早触发(蓝线代表DOMContentLoaded ,红线代表load事件): 在此处输入图片说明

但是,如果您使用 Javascript(不是异步或延迟),则DOM创建将等待 JS 加载。 由于 JS 也会修改 CSS,因此 JS 会等待CSSOM加载。

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

加载链如下所示:

在此处输入图片说明

所以DOMContentLoadedload之间的主要区别在于,在这种情况下,只有图像的加载时间,可以与样式表和 JS 并行下载。

在此处输入图片说明

并不是说如果您对 JS 使用 async 或 defer 就不会发生这种情况:

在此处输入图片说明

这是一些对我们有用的代码。 我们发现 MSIE 被DomContentLoaded命中和错过,当没有缓存其他资源时似乎有一些延迟(根据我们的控制台日志记录最多 300 毫秒),并且当它们被缓存时触发太快。 所以我们对 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、window.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 秒后开始运行

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM