HTML DOM文档加载是按顺序执行的,这与浏览器的渲染方式有关系,一般浏览器渲染操作的顺序如下:
第1步,解析HTML结构。
第2步,加载外部脚本和样式表文件。
第3步,解析并执行脚本代码。
第4步,构造HTML DOM模型。
第5步,加载图片等外部文件。
第6步,页面加载完毕。
例如,下面这个简单的DOM文档。
<html>
<head>
<title>网页标题</title>
<style type="text/css">
body{font-size:12px;}
</style>
<link href="style.css"rel="stylesheet"type="text/css"media="all">
<script src="js.js"type="text/javascript"></script>
</head>
<body>
<p>
<script type="text/javascript">
function f1{}
</script>
<img src="1.gif"/>
</p>
<script type="text/javascript">
function f2{}
</script>
</body>
</html>
这个文档的加载和构造顺序如下,所谓构造就是把对应的标签元素添加到DOM文档对象模型中。
html→head→title→#text(网页标题)→style→加载样式→解析样式→link→加载外部样式表文件→解析外部样式→script→加载外部脚本文件→解析外部脚本→执行外部脚本→body→p→script→加载脚本→解析脚本→执行脚本→img→script→加载脚本→解析脚本→执行脚本→加载外部图像文件→页面初始化完毕。
通过上面的HTML DOM加载顺序,可以看到网页头部的脚本(由外部文件加载)会在构造HTML DOM文档结构之前执行,这就会导致执行脚本无法访问文档结构模型。所以,一般可执行脚本都放在页面初始化事件处理函数中,这样能够确保完全加载完文档之后再执行脚本。
但是,如果页面中包含很多外部文件,如大量图片、视频、音频、动画等文件,可能会延迟脚本的执行时间。为了避免JavaScript脚本处于较长时间的等待,可以把需要执行的脚本分块放在HTML文档结构中间,这样只要在构造DOM后执行到脚本所在结构位置,就会执行脚本。
这种方法虽然能够提前执行脚本,但是不能够保证脚本可以访问该位置后面的文档结构,因为这些文档结构还没有被构造。不过,如果在页面最后一个元素之前嵌入脚本,就可以最早执行脚本,并能够确保脚本可以访问HTML文档结构模型中所有元素。例如:
<html>
<head>
<title></title>
</head>
<body>
<!--文档结构-->
<script language="javascript"type="text/javascript">
//JavaScript执行脚本</script>
</body>
</html>
上述方法容易破坏文档的结构,使整个文档看起来很混乱,不利于管理。可以利用一种间接的方法来实现文档结构的有序显示,当加载完DOM文档后,也意味着Document对象的属性加载完毕,这样可以判断Document对象的几个重要方法,如果存在,则说明DOM已经加载完毕,否则说明DOM还在加载中。通过这种方法既不影响文档结构,又可以快速捕捉到DOM加载的过程,实现的代码如下:
function f{
if(document&&document.getElementsByTagName&&document.getElementById&&document.body){
clearInterval(timer);
//JavaScript执行脚本
}
}
var timer=setInterval(f,10);
在函数f中,首先判断Document对象的几个重要方法是否已经加载完毕,如果加载完毕,则说明DOM结构已经完成加载,执行预定的JavaScript脚本。为了能够实时跟踪加载过程,这里设计了一个定时器,不断调用函数f,以便快速、准确地判断DOM加载状态。如果DOM加载完毕,则清除定时器,并开始执行脚本。