JavaScript判断DOM何时加载完毕的技巧


Posted in Javascript onNovember 11, 2012

处理HTML DOM文档存在一个难题是,JavaScript可以在DOM完全加载之前执行,这会给你的代码引发不少的潜在问题。浏览器的渲染和操作顺序大致如下列表:

HTML解析完毕
外部脚本和样式表加载完毕
脚本在文档内解析并执行
HTML DOM完全构造起来
图片和外部内容加载
网页完成加载

在网页头部并且从外部文件加载的脚本会在HTML真正构造之前执行。如前所述,这是个至关重要的问题,因为这两处执行的脚本并不能访问还不存在的DOM。幸好,我们还有若干的补救方法。
目前,最常用的级数是完全等待整个页面加载完毕才执行DOM操作。这种技术只需利用window对象的load事件来绑定一个函数,页面加载完毕即可触发。

addEvent(window, "load", function(){ 
// do something 
});

最简单的操作却是最慢的。在加载过程的顺序列表中,你会注意到页面的加载完毕与否完全被最后一步所掌控。这就是说,如果页面有很多的图片、视频等,用户可能得登上一段时间JavaScript才执行。
另一种级数可用以监听 DOM 加载状态,可能是最复杂的(从实现角度来看),但也是最有效地。
这项技术在不堵塞浏览器加载的情况下尽可能快地检查 HTML DOM文档是否已经加载了执行所必须得属性。以下是检查HTML DOM是否可用的几个要点:

document: 你需要知道DOM文档是否已经加载。若能足够快地检查,运气好的话你会看到undefined。
document.getElementsByTagName和document.getElementById:频繁使用document.getElementsByTagName和document.getElementById函数检查文档,当存在这些函数则表明DOM已经加载完毕。
document.body: 作为额外补充,检查元素是否已经完全加载。理论上前一个检查应该已经能做出判断,但我发现有些情况下还是不够。
使用这些检查就足够判断DOM是否可用了(“足够”在此表示可能会有一定毫秒级的时间差)。这个方法几乎没有瑕疵。单独使用前述检查,脚本应该可以在现代浏览器中运行得相对良好。但是,最近(2008年?)Firefox实现了缓存改进,使得window加载事件实际上可以在脚本能检查到DOM是否可用之前触发。为了能发挥这个优势,我同时为window加载事件附加检查,以期能获得更快的执行速度。

最后,domReady函数集合了所有需要在DOM可用时就执行的函数的引用。一旦DOM被认为是可用的,就调用这些引用并按顺序一一执行。

// 监听 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; 
} 
} 
}

现在我们来看看在HTML文档中是如何执行的。假设已经将domReady函数写到一个名为domready.js的外部文件中
<html> 
<head> 
<title> Testing DOM Loading</title> 
<script src="domready.js"></script> 
<script> 
domReady(function(){ 
alert("The DOM is loaded!"); 
// do something 
}); 
</script> 
</head> 
<body> 
<h1>Testing DOM Loading</h1> 
<!-- 这里是大量的HTML --> 
</body> 
</html>
Javascript 相关文章推荐
用js做一个小游戏平台 (一)
Dec 29 Javascript
jQuery最佳实践完整篇
Aug 20 Javascript
推荐9款炫酷的基于jquery的页面特效
Dec 07 Javascript
流量统计器如何鉴别C#:WebBrowser中伪造referer
Jan 07 Javascript
angularjs学习笔记之三大模块(modal,controller,view)
Sep 26 Javascript
jQuery密码强度检测插件passwordStrength用法实例分析
Oct 30 Javascript
JavaScript实现横线提示输入验证码随输入验证码输入消失的方法
Sep 24 Javascript
jQuery实现 上升、下降、删除、添加一行代码
Mar 06 Javascript
layui select动态添加option的实例
Mar 07 Javascript
Vue 中mixin 的用法详解
Apr 23 Javascript
详解vue2.0 资源文件assets和static的区别
Nov 27 Javascript
在vue中使用防抖和节流,防止重复点击或重复上拉加载实例
Nov 13 Javascript
JavaScript中的匀速运动和变速(缓冲)运动详细介绍
Nov 11 #Javascript
jQuery语法总结和注意事项小结
Nov 11 #Javascript
javascript继承之为什么要继承
Nov 10 #Javascript
jquery表单验证使用插件formValidator
Nov 10 #Javascript
js 判断checkbox是否选中的操作方法
Nov 09 #Javascript
JS的replace方法详细介绍
Nov 09 #Javascript
获取div编辑框,textarea,input text的光标位置 兼容IE,FF和Chrome的方法介绍
Nov 08 #Javascript
You might like
NOD32 v2.70.32 简体中文封装版 提供下载了
2007/02/27 PHP
一漂亮的PHP图片验证码实例
2014/03/21 PHP
win10环境PHP 7 安装配置【教程】
2016/05/09 PHP
PHP实现分布式memcache设置web集群session同步的方法
2018/04/10 PHP
ThinkPHP实现的rsa非对称加密类示例
2018/05/29 PHP
PHP利用Mysql锁解决高并发的方法
2018/09/04 PHP
IE6下出现JavaScript未结束的字符串常量错误的解决方法
2010/11/21 Javascript
jQuery 选择器、DOM操作、事件、动画
2010/11/25 Javascript
Jquery实现仿京东商城省市联动菜单
2015/11/19 Javascript
JS中Eval解析JSON字符串的一个小问题
2016/02/21 Javascript
Js获取图片原始宽高的实现代码
2016/05/17 Javascript
用 js 的 selection range 操作选择区域内容和图片
2017/04/18 Javascript
javascript将非数值转换为数值
2018/09/13 Javascript
为react组件库添加typescript类型提示的方法
2020/06/15 Javascript
jQuery 实现DOM元素拖拽交换位置的实例代码
2020/07/14 jQuery
[43:41]VP vs RNG 2019国际邀请赛淘汰赛 败者组 BO3 第二场 8.21.mp4
2020/07/19 DOTA
Python之PyUnit单元测试实例
2014/10/11 Python
Python操作串口的方法
2015/06/17 Python
星球大战与Python之间的那些事
2016/01/07 Python
Python实现以时间换空间的缓存替换算法
2016/02/19 Python
python模拟登录并且保持cookie的方法详解
2017/04/04 Python
python实现对指定输入的字符串逆序输出的6种方法
2018/04/26 Python
python爬取微信公众号文章
2018/08/31 Python
python实现手机销售管理系统
2019/03/19 Python
Pyqt5如何让QMessageBox按钮显示中文示例代码
2019/04/11 Python
用 python 进行微信好友信息分析
2020/11/28 Python
css3新单位vw、vh的使用教程
2018/03/23 HTML / CSS
日本著名化妆品零售网站:Cosme Land
2019/03/01 全球购物
Silk Therapeutics官网:清洁、抗衰老护肤品
2020/08/12 全球购物
体育教育个人自荐信范文
2013/12/01 职场文书
早会主持词
2014/03/17 职场文书
一年级学生评语大全
2014/04/21 职场文书
元旦联欢会策划方案
2014/06/11 职场文书
元旦标语大全
2014/10/09 职场文书
2019年暑期法院实习报告
2019/12/18 职场文书
go:垃圾回收GC触发条件详解
2021/04/24 Golang