dom ready的学习
思路:1.调用dom.ready时,先判断下dom是否ready了,如果dom已经ready,则直接执行函数,否则,推入readyList数组等待执行。
2.判断domready,标准浏览器下,有document.DOMContentLoaded事件表明domready,而IE下,则通过doScroll来模拟,原理是在IE中,任何DOM元素都有一个doScroll 方法。当documentElement可以调用doScroll时,证明dom加载完成了。
判断domready的原理如上,但在实际应用中,我看到很多代码都是在进行上面的判断前,先判断document.readyState === 'complete',在正美的http://www.cnblogs.com/rubylouvre/archive/2009/12/30/1635645.html这篇文章里,有列举了文档的加载顺序,列举的第3点不知能否解释上面的疑问,但我印象中好像readyState都是要在onreadystatechange里判断的。在下面的IE判断分支里,则有绑定了document的onreadystatechange事件进行判断。还有个疑问是在很多代码中,看到在执行doScroll时,先判断下是不是在iframe中,不是才调用。我想可能是因为执行到iframe里面时,dom应该都是加载完成的了吧,所以如果是在iframe中的话,就没有必要在进行doScroll判断了,纯属猜测。
var dom = {
isReady: false, //用于标识dom加载是否完成
readyList: [], //用于存放dom ready要执行的函数
//用于当dom ready时,调用此函数依次执行存放在readyList里的函数
fireReady: function(){
if(this.isReady) return;
this.isReady = true;
if(this.readyList){
var i = 0,readyFn;
while(readyFn = this.readyList[i++]){
readyFn();
}
this.readyList.length = 0; //执行到这里时,readyList数组则可以回收了,有人用this.readyList = undefined,也有人将this.readyList.length = 0,以标识此数组可回收。具体是怎样,我其实不知道,这里我选择将length清空的做法。
}
},
ready: function(fn){
if(this.isReady){
return fn(); //这里,既然dom已经ready了,下面的代码就不需要执行了。所以直接执行函数并返回。
}else{
this.readyList.push(fn);
}
//不明白
if(document.readyState === 'complete'){
return this.fireReady();
}
if(document.addEventListener){ //标准浏览器
document.addEventListener('DOMContentLoaded',function(){
document.removeEventListener('DOMContentLoaded',arguments.callee,false);
dom.fireReady();
},false)
}else{ //IE
document.attachEvent('onreadystatechange',function(){
document.detachEvent('onreadystatechange',arguments.callee);
dom.fireReady();
});
(function(){
try{
document.documentElement.doScroll('left');
}catch(e){
setTimeout(arguments.callee,4);
return;
}
dom.fireReady();
})();
}
}
};
dom.ready(function(){
alert('domready1')
})
dom.ready(function(){
alert('domready2')
})
setTimeout(function(){
dom.ready(function(){
alert('延迟2秒,测试domready后的执行');
});
}, 2000);
测试代码:
参考文章或代码:
http://www.cnblogs.com/rubylouvre/archive/2009/08/26/1554204.html
http://www.cnblogs.com/rubylouvre/archive/2009/12/30/1635645.html
http://www.cnblogs.com/rubylouvre/archive/2010/04/15/1712780.html
浙公网安备 33010602011771号