首页 » 编写高质量代码:改善JavaScript程序的188个建议 » 编写高质量代码:改善JavaScript程序的188个建议全文在线阅读

《编写高质量代码:改善JavaScript程序的188个建议》建议107:应理清HTML DOM加载流程

关灯直达底部

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加载完毕,则清除定时器,并开始执行脚本。