您的位置:首页 > Web前端 > JavaScript

自己构建一个domReady.js

2017-02-03 19:10 357 查看
用过jQuery的人们想必对这句话都不陌生“$(document).ready(function(){ func(xxx)//执行函数}); “,还有两种表现形式就不一一列举了,这个其实就是jQuery的domReady函数,在进行dom操作的时候保证所有的dom元素完全被加载!

举个例子

我们执行下面一段代码,让h1内的元素变红,按照下面的执行顺序显然是不可能的,简单的理解就是js在选择h1标签的时候,h1的dom结构还没有生成,当然如果稍作改动也是可以达到预期效果的,比如加一个
window.onload
函数,但是今天就不采用这种方式来解决,原因一会儿在进一步阐述。

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<script type="text/javascript">
document.getElementById("h1").style.color = "red";
</script>
<body id="box">
<h1 id="h1">hhhhh</h1>
</body>
</html>


html标签和dom节点之间的关系

出现上边那种情况就是没有理解html标签和dom节点之间的关系,html是一种标记语言,它告诉我们这个页面的内容,但是行为操作是需要通过dom操作来实现的。html标签通过浏览器解析后变成dom节点,当加载页面的时候dom节点会以dom tree的形式组织,当所有的dom节点都构建完毕,就可以理解为dom ready

html标签如何变成dom节点

浏览器通过渲染引擎来实现,它的作用就是把请求的内容渲染到页面上,默认情况下渲染引擎可以渲染html,xml,图片,但是也可通过插件来显示其他的文件,比如pdfviewer来显示pdf文档。

渲染流程

首先解析html,构建dom树(构建dom节点)

构建渲染树(解析样式信息)

布局渲染树(布局dom节点)

绘制渲染树(绘制dom节点)

webkit渲染流程图



window.onload

window.onload是等待页面所有dom节点加载完毕后在执行js代码,代码如下

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<script type="text/javascript">
window.onload = function(){
document.getElementById("h1").style.color = "red";
}
</script>
<body id="box">
<h1 id="h1">hhhhh</h1>
</body>
</html>


那为什么放弃window.onload呢,当页面结构不多的时候用window.onload是完全没有问题的。举个小例子吧,现在有这样的一个需求,在页面内请求100张远程加载的图片,并且要求点击图片的时候alert出图片地址,这时候会发现dom节点会很快的创建完毕,但是图片的资源可没有那么快的就能加载完毕,这时候页面就会出现问题,对用户体验大打折扣。

domReady实现

domReady实现策略

1.支持DOMContentLoaded的事件,就使用DOMContentLoaded

2.不支持的就使用Hack兼容,其原理是通过
document.documentElement.doScroll('left')
来判断dom树是否创建完毕。

自个儿封装

function myReady(fn){
//兼容ie及其他
if(document.addEventListener){
document.addEventListener("DOMContentLoaded",fn,false)
}else{
IEContentLoaded(fn)
}
//ie模拟DOMContentLoaded
function IEContentLoaded(fn){
var d = window.document;
var done = false;
//只执行一次用户的回调函数init()
//      确保domready函数只执行一次
var init = function(){
if (!done){
done = true;
fn()
}
};
//立即调用
(function(){
try {
//dom为创建完成之前调用doScroll会抛出错误
d.documentElement.doScroll('left');
} catch(e){
//延迟再试一次,调用函数自身
setTimeout(arguments.callee,50);
return;
}
// 没有错误表示dom创建完毕,然后立马执行用户回调
init()
})();
//监听document的加载状态
d.onreadystatechange = function(){
// 如果用户在domready后绑定函数,立即执行
if(d.readyState == 'complete'){
d.onreadystatechange = null;
init();
}
}
}
}


例子代码

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<script src="domReady.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
myReady(function(){
document.getElementById("h1").style.color = "red";
})
</script>
<body id="box">
<h1 id="h1">hhhhh</h1>
</body>
</html>


番外篇

大家可以通过这个地址看一下各个主流框架domready实现函数
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  dom javascript