https://developer.mozilla.org/zh-CN/docs/Web/API/Window/DOMContentLoaded_event https://zh.javascript.info/onload-ondomcontentloaded
自己测试的例子(这个比较形象哈)
一个html文件如下:
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title></head><body><div><div><h1>testteststest</h1><div><h1>testteststest</h1><div><h1>testteststest</h1></div></div></div></div><script>document.addEventListener('DOMContentLoaded', () => {console.log('DOM now:' + new Date().getTime());})</script><script src="http://127.0.0.1:8000/gb-web/static/test.js"></script></body></html>
其中最下面的script标签放到了nginx服务器里面,代码如下:
console.log('test-----------' + new Date().getTime())for(let i = 0; i < 1000; i++) {console.warn(i)}
第一次
运行html文件,发现DOL触发时机是在test.js打印完成之后

第二次
这个时候,如果我们把最下面的script标签添加async属性,则DCL会先触发(可能先,也可能后)
第三次
还有一种情况,如果我们test.js没有async属性,同时里面的js有异步操作,会是什么情况呢???
我们把test.js修改如下:
console.log('test-----------' + new Date().getTime())setTimeout(() => {console.warn(111)}, 1000);
html运行如下:
test.js会正常执行,但是遇到异步的时候,则会先触发DCL
定义
当初始的 HTML 文档被完全加载和解析完成之后,DOMContentLoaded 事件被触发,而无需等待样式表、图像和子框架的完全加载
DOMContentLoaded是document上的api
<script>function ready() {alert('DOM is ready');// 图片目前尚未加载完成(除非已经被缓存),所以图片的大小为 0x0alert(`Image size: ${img.offsetWidth}x${img.offsetHeight}`);}document.addEventListener("DOMContentLoaded", ready);</script><img id="img" src="https://en.js.cx/clipart/train.gif?speed=1&cache=0">
在示例中,DOMContentLoaded 处理程序在文档加载完成后触发,所以它可以查看所有元素,包括它下面的 元素。
但是,它不会等待图片加载。因此,alert 显示其大小为零。
乍一看,DOMContentLoaded 事件非常简单。DOM 树准备就绪 —— 这是它的触发条件。它并没有什么特别之处。
怎么理解呢?
第一种情况
如果body里面只有html的dom结构,中间(这个中间是说整个body里头,而不是html里头)没有script标签,则DOMContentLoaded事件会在DOM树构建完成之后触发,无需等待其他资源加载完成(比如img、css等)
<link type="text/css" rel="stylesheet" href="style.css"><script>// 在样式表加载完成之前,脚本都不会执行alert(getComputedStyle(document.body).marginTop);</script>
原因是,脚本可能想要获取元素的坐标和其他与样式相关的属性,如上例所示。因此,它必须等待样式加载完成。
当 DOMContentLoaded 等待脚本时,它现在也在等待脚本前面的样式。
第二种情况
如果DOM结构中,存在script标签
因为html是自上而下解析,如果遇到script标签,则需要加载标签并且执行,如果是内联script,则直接执行,等到js执行完成之后,会继续解析DOM节点,就算把script标签放最下面,也是会影响DOMConteLad的
这儿需要注意的是:
- DOM等待js执行,而js又需要等待css加载完成,所以这种情况下,DOMContendLoaded会更往后触发
- 如果script是外部引入,并且添加了async属性,则不会阻碍出发DOMContentLoaded
- 如果script是动态生成的,效果跟加入async属性一致 ```javascript
``` 在上面这个例子中,我们首先会看到 “Library loaded…”,然后才会看到 “DOM ready!”(所有脚本都已经执行结束)。
