请考虑以下代码:
$("#theform").submit(function (e) {
e.preventDefault();
var locdiv=$("#maindiv");
var locations = locdiv.children();
var loc = [];
for (var i = 0; i < locations.length; i++)
{
loc.push(locations.eq(i).text());
}
// SaveLocations(loc);
$("#packagelist").val(loc);
$("#theform").submit();
令我惊讶的是,DOM延迟加载十秒钟(10秒后出现 .box矩形!)。因为它是第一个<head>
<style>
.box{
background-color:red;
height:150px;
width:150px;
}
</style>
</head>
<body>
<div class="box"></div>
<script>
var start = new Date();
while(true) {
var now = new Date();
if (now-start > 10000)
break;
}
console.log('main thread finished');
</script>
</body>
,为什么还要等待下面的脚本?有任何合理的解释吗?
谢谢
答案 0 :(得分:2)
“没有异步或延迟属性的脚本,以及内联脚本, 在浏览器继续之前立即获取并执行 解析页面。“ - 来自MDN。
所以你的脚本停止解析10秒钟。不要谈论渲染页面。基本上这样做是为了支持执行脚本中的立即html修改。例如,如果您的脚本调用document.write('More html')
,则会影响解析。
顺便说一下,执行脚本可以访问已经解析的DOM结构。请考虑以下示例。
<div class="box">Affected</div>
<script>
[].forEach.call(document.querySelectorAll('.box'), function(box){
box.innerText += '... modified';
});
</script>
<div class="box">Not</div>
答案 1 :(得分:1)
为了简化它,JavaScript是单线程的,这意味着它无法在处理您的小脚本的同时处理DOM模型。它是一个又一个。
可以找到真正全面的豁免here。
为避免用户界面被阻止,您可能有兴趣了解 Web Workers 。
答案 2 :(得分:1)
答案 3 :(得分:0)
此脚本不会等待页面在启动之前完全加载。所以这就是你等了10秒的原因。这就是为什么这样的代码通常由window.onload或$(document).ready()包装的原因。
答案 4 :(得分:0)
根据标准,浏览器可以在脚本执行之前呈现该元素。但它并不意味着它必须。我在4个浏览器中检查了你的代码,其中只有一个在脚本执行之前绘制了.box
- 它是Opera 12.所有其他浏览器 - Chrome,FF,IE11都没有。
正如我记得的那样,有时铬会说它可以让他们优化一些东西,他们认为互联网速度变得足够大,可以等到满载。