面试的时候遇到了这样一个问题,如下的html页面,最终页面上输出的是什么?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>DOM加载顺序</title>
<script src="../libs/jquery.min.js"></script>
</head>
<body>
<p>1</p>
<script>
document.write('2')
</script>
<p>3</p>
<script>
window.onload = function () {
document.write('4');
document.write('5');
setTimeout(function () {
document.write('8')
}, 1000)
};
setTimeout(function () {
document.write('6')
}, 0);
setTimeout(function () {
document.write('7')
}, 1000)
</script>
</body>
</html>
|
|
|
想
一
想
|
|
|
先不说答案,我当时的答案和思路是这样的:
最后页面展现的是:45678
分析:123的顺序很好理解,这时候window.load
函数还没有执行,但是在第二段脚本中,setTimeOut
和window.onload
都是在DOM完全加载完毕后执行,document.write
相当重新书写了页面,导致123
被取消,在页面上消失
你认为对吗?
自己把这段代码复制到IDE中,打开一个页面看一看吧?
最终的结果是页面上只展现了6和7,原因是:页面从上向下解析,首先出现1,然后继续解析,遇到了document.write('2')
,所以屏幕上出现2,然后继续解析,出现3
接着遇到了<srcipt>
标签,onload的函数肯定会暂缓执行,因为这时候页面还没有解析完成,然后遇到了延时0s的document.write('6')
,放入任务队列当中,然后又将延时1s的document.write('7')
放到了任务队列。这时候,肯定延时0s的document.write('6')
比页面解析完成的更快,所以先执行了,这样直接就将页面重写了,window.onload
这段代码根本就被重写了,这时候页面是这样的:
<html>
<head></head>
<body>6</body>
</html>
1s后变成了:
<html>
<head></head>
<body>67</body>
</html>
所以最终输出结果是67
其实最终输出的关键在于document.write('6')
的延时与DOM解析完毕谁先完成,和浏览器的解析速度有关
我试验了一下,对于这样一个既简单的页面,chrome解析大概需要100ms,所以如果document.write('6')
的延时小于100ms就会出现上面的结果,如果大于100ms的话(比如200ms),页面最终显示的就是45678
7和8的顺序,聪明的你应该理解吧。