首页 > 关于0毫秒的超时调用(替代DOMContentLoaded事件)?

关于0毫秒的超时调用(替代DOMContentLoaded事件)?

javascript高级程序设计中讲到DOMContentLoaded事件时,有这样一段代码:

setTimeout(function(
    //在此添加事件处理程序
),0);

目的是模拟DOMContentLoaded的功能(IE8以下不支持DOMContentLoaded),其解释是

在当前javaScript处理完成后立即运行这个函数。

该怎么理解?


DOM树的创建js,css,image等资源文件的加载,setTimeout代码块他们之间是怎样的一种执行顺序?


本来我也完全不知道为什么,直到一楼告诉了我真相。我就想说的是DOM树的构建不是完全同步的,因为JS的执行可能修改DOM,所以(在没有设置defer,async)等属性的<script>都是阻塞式的加载和执行。于是乎我就想到如下代码:

<html>
<head>
<meta charset='utf8'>
    <script type="text/javascript">
    setTimeout(function(){
        var div1 = document.getElementById('event1');
        console.log(div1);
    },0);
    document.addEventListener('DOMContentLoaded',function(){
        var div1 = document.getElementById('event1');
        console.log(div1);
    },false);
    </script>
    <script type="text/javascript">
    for(var x=0;x<5e8;x++){}//模拟占用大大大量时间js代码
</script>
</head>
<body>
    <div id="event1"></div>
</body>
</html> 

放到chrome下运行之后,setTimeout和我想的一样(虽然时间上试了好几次才成功0.0)不一定能够完全模拟DOMContentLoaded,特别是在你接下来要执行一段一个运算量很大需要很多时间的JS的时候。不过在时间间隔比较小的时候,我测试的setTimeout表现还是和DOMContentLoaded很一致的。


setTimeout不是严格的按照设定的时间间隔之后执行的,应该是指最早在x毫秒之后执行,也就是把任务添加到事件队列的末端执行。

setTimout(func,0),是把其中的代码移到下一次时间片执行,也就是说等待所有同步任务(构建DOm树)执行完之后,再执行func。


根据一楼 @愚吉啦啦 ,二楼 @x31494jp 的回答,再加上这篇文章:setTimeout和setInterval的区别你真的了解吗? 会理解的更透彻点。
文章中有一个关键点:

javascript都是以单线程的方式运行于浏览器的javascript引擎中的, setTimeout和setInterval的作用只是把你要执行的代码在你设定的一个时间点插入js引擎维护的一个代码队列中, 插入代码队列并不意味着你的代码就会立马执行的

【热门文章】
【热门文章】