javascript第一次添加到web浏览器时,还没有API 可以用来遍历和操作文档的结构和内容。当文档还在载入时,javascript影响文档内容的唯一方法是快速生成内容。它使用document.write()方法完成上述任务。
当脚本把文本传递给document.write()时,这个文本被添加到文档输入流中,html解析器会在当前位置创建一个文本节点,将文本插入这个文本节点后面。不推荐使用!
但在某些场景下它有着重要的用途。当HTML解释器遇到<script>元素时,它默认必须先执行脚本,然后再恢复文档的解析和渲染。这对于内联脚本没什么问题,但如果脚本源代码是一个由src属性指定的外部文件,这意味着脚本后面的文档部分在下载和执行脚本之前,都不会出现在浏览器。
脚本的执行只在默认情况下是同步和阻塞的。<script>标签中可有defer和async属性,这可以改变脚本的执行方式。这些都是布尔属性,没有值;只需要出现在标签里即可。HTML5说这些属性只在和src属性联合使用时才有效,但有些浏览器还支持延迟的内联脚本:
<script defer src="deferred.js"></script>
<script async src="async.js"></script>
defer asyne属性都像是在告诉浏览器链接进来的脚本不会使用document.write(),也不会生成文档内容,因此浏览器要以在下载脚本时继续解析和渲染文档。
defer属性使得浏览器延迟脚本的执行,直到文档的载入和解析完成,并可以操作。
async属性使得浏览器可以尽快地执行脚本,而不用在下载脚本时阻塞文档解析。如果浏览器同时支持两个属性,会遵从async属性而忽略defer属性。
注意延迟的脚本会按他们在文档里出现的顺序执行。而异步在它们载入后执行,这意味着它们可能会无序执行。
在不支持async属性的浏览器里,通过动态创建<script>元素并把它插入到文档中,来实现脚本的异步载入和执行。
function loadasync(url){
varhead = document.getElementsByTagName("head")[0];
vars = document.createElement("script");
s.src = url;
head.appendChild(s);
}