浅谈DOMContentLoaded事宜及其封装要领

我们在开辟时,常常须要检测页面是不是加载终了,以确保剧本平安运转,下面我们就来浅谈一下检测页面是不是加载终了的那些事宜们。

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,起首注册documentonreadystatechange事宜,这是为了防止当页面处于iframe中时,doScroll要领会失效,因而在完成代码中做了推断。以后,推断假如是IE而且页面不在iframe当中, 则经由过程setTimeout来不停的挪用:

document.documentElement.doScroll('left');

直到挪用胜利,代表DOM加载完成。

总结一下,开辟时我们能够经由过程封装DOMContentLoaded事宜来检测页面DOM是不是加载终了,然后实行逻辑代码,提拔用户体验。

    原文作者:hantingting
    原文地址: https://segmentfault.com/a/1190000005869515
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞