javascript - 关于0毫秒的超时调用(替代DOMContentLoaded事件)?
迷茫
迷茫 2017-04-10 15:44:00
[JavaScript讨论组]

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

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

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

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

该怎么理解?


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

迷茫
迷茫

业精于勤,荒于嬉;行成于思,毁于随。

全部回复(3)
伊谢尔伦

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

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

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

阿神

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

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

PHPz

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

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

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号