处理HTML DOM文档存在的一个的难题是,JavaScript可以在DOM完全加载之前执行,这会带来很多的潜在问题。浏览器的渲染和操作顺序大致如下:
浏览器的渲染和操作顺序:
HTML解析完毕
外部脚本和样式表加载完毕
脚本在文档内解析并执行
HTML DOM完全构造出来
图片和外部内容加载
网页完成加载
在网页头部或者从外部文件加载的脚本会在HTML真正构造之前执行,导致脚本还不能访问还不存在的DOM。
1. 等待整个页面的加载
最常用的技术是完全等待整个页面加载完毕之后才执行DOM操作。这种技术在window对象的load事件上绑定一个函数,页面加载完毕后触发该函数。
// 等到页面加载完毕 addEvent(window, "load", function() { // 执行 HTML DOM 操作 next( id("everywhere") ).style.background = 'blue'; });
2. 等待大部分DOM的加载
因为只有在DOM构造后,执行到该位置的脚本才真正执行。这意味着中途嵌入的脚本只能访问该位置之前的DOM。所以页面最后元素之前嵌入脚本,就可以在DOM中访问这个元素之前全部的脚本。
<html> <head> <title>Testing DOM Loading</title> <script type="text/javascript"> function init() { alert( "The DOM is loaded!" ); tag("h1")[0].style.border = "4px solid black"; } </script> </head> <body> <h1>Testing DOM Loading</h1> <!—这里是大量的HTML --> <script type="text/javascript">init();</script> </body> </html>
3. 判断DOM何时加载完毕
在不堵塞浏览器加载的情况下尽可能快地检查HTML DOM文档是否已经加载了执行所必需的属性。这些检查包括:
(1)document: 判断DOM文档是否已经加载
(2)document.getElementsByTagName 和 document.getElementById: 当存在这些函数则表明已完成加载
(3)document.body: 作为额外补充
执行以上的检查,脚本应该可以在现代浏览器中运行得相对良好。下面的 domReady 函数集合了这些检查。一旦DOM被认为是可用的,就调用这些引用并按顺序执行。
function domReady( f ) { // 如果DOM加载完毕,执行函数 if ( domReady.done ) return f(); // 已经增加了一个函数 if ( domReady.timer ) { // 把它加入到待执行的函数清单中 domReady.ready.push( f ); } else { // 为页面加载完毕绑定一个事件 addEvent( window, "load", isDOMReady ); // 初始化待执行函数的数组 domReady.ready = [ f ]; // 尽可能快地检查DOM是否已经可用 domReady.timer = setInterval( isDOMReady, 13 ); } } // 检查DOM是否已可操作 function isDOMReady() { // 如果DOM已可用,则忽略 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[i](); domReady.ready = null; domReady.done = true; } } [/code] 假设已经将 domReady 函数写到一个名为 domready.js 的外部文件中,则它的使用是: [code lang="html"] <html> <head> <title>Testing DOM Loading</title> <script type="text/javascript" src="domready.js"></script> <script type="text/javascript"> domReady(function() { alert( "The DOM is loaded!" ); tag("h1")[0].style.border = "4px solid black"; }); </script> </head> <body> <h1>Testing DOM Loading</h1> <!—这里是大量的HTML --> </body> </html>
转载请注明:陈童的博客 » DOM — 等待HTML DOM 的加载