我们在开辟时,常常须要检测页面是不是加载终了,以确保剧本平安运转,下面我们就来浅谈一下检测页面是不是加载终了的那些事宜们。
1. onload 事宜
在页面的一切资本加载完成时,window对象上会触发一个onload
事宜。该事宜通常被用以实行一些逻辑代码。比方,你须要经由过程JS去接见一个DOM。
<script>
console.log(document.getElementById('name').innerHTML);
</script>
<div id="name">chengxuyuan</div>
上述代码运转时肯定会报错,由于剧本实行时,id为name的div
还没有加载完成。那末什么机遇才是我们猎取DOM文档的牢靠机遇呢?恰是我们上面说道的onload
,页面的onload
触发时,证实页面文档流及资本已完整加载终了,此时,猎取在文档流中的DOM是最“平安”的机遇。我们将上述代码加以革新,以下:
<script>
window.onload = function () {
console.log(document.getElementById('myname').innerHTML);
}
</script>
<div id="myname">chengxuyuan</div>
再次运转时,代码便不会报错了。因而,onload
事宜的实际效果是当页面剖析完DOM树,而且完成了一切图片、样式表、剧本等资本的加载后才被触发。那末题目来了,当资本过量过大时,onload
会涌现比较严重的耽误题目,严重影响用户体验。
2. DOMContentLoaded 事宜
对照上述情况,Firefox的DOMContentLoaded
事宜就越发合理,该要领触发的时候更早,它在DOM内容加载完后就触发,无需守候其他资本的加载完成。
<script>
window.onload = function () {
console.log('页面资本悉数加载终了');
}
document.addEventListener("DOMContentLoaded", function(event) {
console.log('DOM已被完整加载和剖析');
});
</script>
上述代码的实行效果为顺次打印出:
DOM已被完整加载和剖析
页面资本悉数加载终了
因而可知,DOMContentLoaded
事宜能更早地捕获到DOM加载完成。
现在,Webkit 525以上版本和Opera也包括该要领。别的,它现在已在HTML5中被标准化。但IE仍不支撑DOMContentLoaded
。
别的,许多JavaScript框架都有document.ready功用,比方jQuery的:
$(document).ready(function(){});
它的中心就是DOMContentLoaded
事宜,能够运用:
document.addEventListener("DOMContentLoaded",function(){...},false);
举行事宜绑定,但照样须要针对IE做兼容性处置惩罚。
3. onreadystatechange 事宜
虽然IE不支撑DOMContentLoaded
,但它支撑onreadystatechange
事宜,该事宜的目标是供应与文档或元素的加载状况有关的信息。支撑onreadystatechange
事宜的每一个对象都有一个readyState
属性,能够包括以下5个值中的一个。
uninitialized
(为初始化):对象存在但还没有初始化。loading
(正在加载):对象正在加载数据。loaded
(加载终了):对象加载数据完成。interactive
(交互):能够操纵对象了,但还没有完整加载。complete
(完成):对象已加载终了。
onreadystatechange
事宜能够用于检测DOM是不是加载终了,当document.readyState == 'complete'
时,示意DOM加载完成。然则假如页面中有iframe
的话,会比及iframe
中的一切资本加载完才会变成complete
。 此时也造成了主页面的耽误。而且,经测试,纵然页面中没有iframe
, 该体式格局也与onload
相称,照旧会比及一切资本下载终了后才触发。
4. doScroll要领
不过,IE另有个特有的要领doScroll
, 经由过程距离挪用:
document.documentElement.doScroll("left");
能够检测DOM是不是加载完成。 当页面未加载完成时,该要领会报错,直到doScroll
不再报错时,就代表DOM加载完成了。该要领更靠近DOMContentLoaded
的完成。
5. Javascript封装DOMContentLoaded事宜
以下,是JS封装DOMContentLoaded
事宜从而到达优越的兼容性的一个简朴的代码完成。
function ready(fn){
// 现在Mozilla、Opera和webkit 525+内核支撑DOMContentLoaded事宜
if(document.addEventListener) {
document.addEventListener('DOMContentLoaded', function() {
document.removeEventListener('DOMContentLoaded',arguments.callee, false);
fn();
}, false);
}
// 假如IE
else if(document.attachEvent) {
// 确保当页面是在iframe中加载时,事宜照旧会被平安触发
document.attachEvent('onreadystatechange', function() {
if(document.readyState == 'complete') {
document.detachEvent('onreadystatechange', arguments.callee);
fn();
}
});
// 假如是IE且页面不在iframe中时,轮询挪用doScroll 要领检测DOM是不是加载终了
if(document.documentElement.doScroll && typeof window.frameElement === "undefined") {
try{
document.documentElement.doScroll('left');
}
catch(error){
return setTimeout(arguments.callee, 20);
};
fn();
}
}
};
关于IE,起首注册document
的onreadystatechange
事宜,这是为了防止当页面处于iframe
中时,doScroll
要领会失效,因而在完成代码中做了推断。以后,推断假如是IE而且页面不在iframe
当中, 则经由过程setTimeout
来不停的挪用:
document.documentElement.doScroll('left');
直到挪用胜利,代表DOM加载完成。
总结一下,开辟时我们能够经由过程封装DOMContentLoaded
事宜来检测页面DOM是不是加载终了,然后实行逻辑代码,提拔用户体验。