https://developer.mozilla.org/zh-CN/docs/Web/API/Window/DOMContentLoaded_event https://zh.javascript.info/onload-ondomcontentloaded

    自己测试的例子(这个比较形象哈)
    一个html文件如下:

    1. <!DOCTYPE html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
    6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
    7. <title>Document</title>
    8. </head>
    9. <body>
    10. <div>
    11. <div>
    12. <h1>testteststest</h1>
    13. <div>
    14. <h1>testteststest</h1>
    15. <div>
    16. <h1>testteststest</h1>
    17. </div>
    18. </div>
    19. </div>
    20. </div>
    21. <script>
    22. document.addEventListener('DOMContentLoaded', () => {
    23. console.log('DOM now:' + new Date().getTime());
    24. })
    25. </script>
    26. <script src="http://127.0.0.1:8000/gb-web/static/test.js"></script>
    27. </body>
    28. </html>

    其中最下面的script标签放到了nginx服务器里面,代码如下:

    1. console.log('test-----------' + new Date().getTime())
    2. for(let i = 0; i < 1000; i++) {
    3. console.warn(i)
    4. }

    第一次
    运行html文件,发现DOL触发时机是在test.js打印完成之后
    image.pngimage.png
    第二次
    这个时候,如果我们把最下面的script标签添加async属性,则DCL会先触发(可能先,也可能后)
    第三次
    还有一种情况,如果我们test.js没有async属性,同时里面的js有异步操作,会是什么情况呢???
    我们把test.js修改如下:

    1. console.log('test-----------' + new Date().getTime())
    2. setTimeout(() => {
    3. console.warn(111)
    4. }, 1000);

    html运行如下:
    test.js会正常执行,但是遇到异步的时候,则会先触发DCL
    image.png

    定义
    当初始的 HTML 文档被完全加载和解析完成之后,DOMContentLoaded 事件被触发,而无需等待样式表、图像和子框架的完全加载
    DOMContentLoaded是document上的api

    1. <script>
    2. function ready() {
    3. alert('DOM is ready');
    4. // 图片目前尚未加载完成(除非已经被缓存),所以图片的大小为 0x0
    5. alert(`Image size: ${img.offsetWidth}x${img.offsetHeight}`);
    6. }
    7. document.addEventListener("DOMContentLoaded", ready);
    8. </script>
    9. <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等)

    1. <link type="text/css" rel="stylesheet" href="style.css">
    2. <script>
    3. // 在样式表加载完成之前,脚本都不会执行
    4. alert(getComputedStyle(document.body).marginTop);
    5. </script>

    原因是,脚本可能想要获取元素的坐标和其他与样式相关的属性,如上例所示。因此,它必须等待样式加载完成。
    当 DOMContentLoaded 等待脚本时,它现在也在等待脚本前面的样式。

    第二种情况
    如果DOM结构中,存在script标签
    因为html是自上而下解析,如果遇到script标签,则需要加载标签并且执行,如果是内联script,则直接执行,等到js执行完成之后,会继续解析DOM节点,就算把script标签放最下面,也是会影响DOMConteLad的
    这儿需要注意的是:

    1. DOM等待js执行,而js又需要等待css加载完成,所以这种情况下,DOMContendLoaded会更往后触发
    2. 如果script是外部引入,并且添加了async属性,则不会阻碍出发DOMContentLoaded
    3. 如果script是动态生成的,效果跟加入async属性一致 ```javascript

    ``` 在上面这个例子中,我们首先会看到 “Library loaded…”,然后才会看到 “DOM ready!”(所有脚本都已经执行结束)。