之后的脚本阻止了DOM加载

时间:2016-02-19 07:53:01

标签: javascript html dom

请考虑以下代码:

$("#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> ,为什么还要等待下面的脚本?有任何合理的解释吗?

谢谢

5 个答案:

答案 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)

由于引擎的工作方式(单线程),任何脚本执行都会阻止脚本中页面中的任何渐进式渲染

enter image description here

答案 3 :(得分:0)

此脚本不会等待页面在启动之前完全加载。所以这就是你等了10秒的原因。这就是为什么这样的代码通常由window.onload或$(document).ready()包装的原因。

答案 4 :(得分:0)

根据标准,浏览器可以在脚本执行之前呈现该元素。但它并不意味着它必须。我在4个浏览器中检查了你的代码,其中只有一个在脚本执行之前绘制了.box - 它是Opera 12.所有其他浏览器 - Chrome,FF,IE11都没有。

正如我记得的那样,有时铬会说它可以让他们优化一些东西,他们认为互联网速度变得足够大,可以等到满载。