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');
// 图片目前尚未加载完成(除非已经被缓存),所以图片的大小为 0x0
alert(`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!”(所有脚本都已经执行结束)。