处理HTML DOM文档存在的一个难题是,JavaScript可以在DOM完全加载之前执行,这会给你的代码引发不少的潜在问题。浏览器的渲染和操作顺序大致如以下列表: l HTML解析完毕。 在网页头部并且从外部文件加载的脚本会在HTML真正构造之前执行。如前所述,这是个至关重要的问题,因为这两处执行的脚本并不能访问还不存在的DOM。幸好,我们还有若干的补救办法。 1、 等待整个页面的加载 目前,最常用的技术是完全等待整个页面加载完毕才执行DOM操作。这种技术只需利用window对象的load事件来绑定一个函数,页面加载完毕即可触发。我们将会在第6章更详细地讨论事件。代码清单5-10展示了一个页面完成加载后执行DOM相关代码的例子。 代码清单5-10 使用addEvent函数为window.onload属性绑定回调函数 // 直到页面加载完毕 // (使用的addEvent, 下一章会有阐述) addEvent(window, "load", function() { 最简单的操作却是最慢的。在加载过程的顺序列表中,你会注意到页面的加载完毕与否完全被最后一步所掌控。这就是说,如果你页面有很多的图片、视频等,用户可能得等上一段时间JavaScript才执行。 2、 等待大部分DOM的加载 第二种技术相当绕弯子,所以并不是十分推荐使用。如果你还记得,前面说过行内的脚本在DOM构造后就可立即执行。这是准真理。只有在DOM构造后,执行到该位置上脚本才真正执行。这意味着在你在页面中途嵌入的行内脚本只能访问该位置之前的DOM。所以,在页面最后元素之前嵌入脚本,你就可以在DOM中访问这个元素之前全部的元素,成为一条模拟DOM加载的伪路子。该方法典型的实现如代码清单5-11所示。 代码清单5-11 依靠在HTML DOM最后插入一个 <h1>Testing DOM Loading</h1> 在这个例子中,你必须把行内脚本作为DOM的最后一个元素,以便它最后一个被解析和执行。它唯一执行的是初始化函数,该函数应该包含你需要操作的DOM的相关代码。这个解决方案的最大问题在于混乱:你为HTML增添无关标记的理由仅仅是检查DOM是否已经执行。该技术通常被认为是不合理的,因为你为页面增加额外的代码的目的只是检查加载状态而已。 3、 判断DOM何时加载完毕 最后一种技术可用以监听DOM加载状态,可能是最复杂的(从实现角度来看),但也是最有效的。在该技术中,你既能像绑定window加载事件那般简单,又能获得行内脚本技术那样的速度。 这项技术在不堵塞浏览器加载的情况下尽可能快地检查HTML DOM文档是否已经加载了执行所必须的属性。以下是检查HTML DOM是否可用的几个要点: (1) document:你需要知道DOM文档是否已经加载。若能足够快地检查,运气好的话你会看到undefined。 使用这些检查就足够判断DOM是否可用了(“足够”在此表示可能会有一定毫秒级的时间差)。这个方法几乎没有瑕疵。单独使用前述检查,脚本应该可以在现代浏览器中运行得相对良好。但是,最近Firefox实现了缓存改进,使得window 加载事件实际上可以在脚本能检查到DOM是否可用之前触发。为了能发挥这个优势,我同时为window加载事件附加检查,以期能获得更快的执行速度。 最后,domReady函数集合了所有需要在DOM可用时就执行的函数的引用。一旦DOM被认为是可用的,就调用这些引用并按顺序一一执行。代码清单5-12展示了一个监听DOM何时加载完毕的函数。 代码清单5-12 监听DOM是否可用的函数 function domReady( f ) { // 假如 DOM 已经加载,马上执行函数 // 假如我们已经增加了一个函数 // 把它加入待执行函数清单中 // 为页面加载完毕绑定一个事件, // 初始化待执行函数的数组 // 尽可能快地检查DOM是否已可用 // 检查DOM是否已可操作 function isDOMReady() { // 如果我们能判断出DOM已可用,忽略 // 检查若干函数和元素是否可用 // 如果可用,我们可以停止检查 // 执行所有正等待的函数 domReady.ready[i](); 现在该来看看这在HTML文档中是如何执行的。domReady函数应该按addEvent函数(第6章将讨论)的方式使用,文档可操作时即绑定你需要执行的函数。代码清单5-13展示了如何使用domReady函数来监听DOM是否可用。在这个例子中,假设已经将domReady函数写到一个名为domready.js的外部文件中。 代码清单5-13 使用domReady函数来确定何时DOM可操作和修改 <title>Testing DOM Loading</title> <!--这里是大量的HTML --> 现在你已经掌握若干定位一般XML DOM文档与如何补救HTML DOM文档加载难题的方法,另一个问题也该摆上台面了:还有更好的方法来查找HTML文档中的元素吗?当然,答案是十分肯定的。
l 外部脚本和样式表加载完毕。
l 脚本在文档内解析并执行。
l HTML DOM完全构造起来。
l 图片和外部内容加载。
l 网页完成加载。
// 执行HTML DOM操作
next( id("everywhere") ).style.background = 'blue';
});
<!-- 这里是大量的HTML -->
(2) document.getElementsByTagName和documents.getElementById:频繁使用docum- ent.getElementsByTagName和document.getElementById函数检查文档,当存在这些函数则表明已完成加载。
(3) document.body:作为额外补充,检查
if ( domReady.done ) return f();
if ( domReady.timer ) {
domReady.ready.push( f );
} else {
// 以防它最先完成。使用addEvent(该函数见下一章)。
addEvent( window, "load", isDOMReady );
domReady.ready = [ f ];
domReady.timer = setInterval( isDOMReady, 13 );
}
}
if ( domReady.done ) return false;
if ( document && document.getElementsByTagName &&
document.getElementById && document.body )
{
clearInterval( domReady.timer );
domReady.timer = null;
for ( var i = 0; i < domReady.ready.length; i++ )
// 记录我们在此已经完成
domReady.ready = null;
domReady.done = true;
}
}
<h1>Testing DOM Loading</h1>
等待HTML DOM的加载
最新推荐文章于 2024-09-21 09:30:15 发布
本文探讨了在HTML DOM文档加载过程中可能出现的问题,并提供了三种解决方案:等待整个页面加载、等待大部分DOM加载及判断DOM何时加载完毕。通过具体示例展示了如何在实践中应用这些策略。

4132

被折叠的 条评论
为什么被折叠?



