资讯专栏INFORMATION COLUMN

浅谈DOMContentLoaded事件及其封装方法

waruqi / 2510人阅读

摘要:事件虽然不支持,但它支持事件,该事件的目的是提供与文档或元素的加载状态有关的信息。事件可以用于检测是否加载完毕,当时,表示加载完成。封装事件以下,是封装事件从而达到良好的兼容性的一个简单的代码实现。

我们在开发时,经常需要检测页面是否加载完毕,以确保脚本安全运行,下面我们就来浅谈一下检测页面是否加载完毕的那些事件们。

1. onload 事件

在页面的所有资源加载完成时,window对象上会触发一个onload事件。该事件通常被用以执行一些逻辑代码。比如,你需要通过JS去访问一个DOM。


chengxuyuan

上述代码运行时肯定会报错,因为脚本执行时,id为name的div还没有加载完成。那么什么时机才是我们获取DOM文档的可靠时机呢?正是我们上面说道的onload,页面的onload触发时,证明页面文档流及资源已经完全加载完毕,此时,获取在文档流中的DOM是最“安全”的时机。我们将上述代码加以改造,如下:


chengxuyuan

再次运行时,代码便不会报错了。因此,onload事件的实际效果是当页面解析完DOM树,并且完成了所有图片、样式表、脚本等资源的加载后才被触发。那么问题来了,当资源过多过大时,onload会出现比较严重的延迟问题,严重影响用户体验。

2. DOMContentLoaded 事件

对比上述情况,Firefox的DOMContentLoaded事件就更加合理,该方法触发的时间更早,它在DOM内容加载完后就触发,无需等待其他资源的加载完成。

上述代码的执行结果为依次打印出:

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是否加载完毕,然后执行逻辑代码,提升用户体验。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/79882.html

相关文章

  • 浅谈DOMContentLoaded事件及其封装方法

    摘要:事件虽然不支持,但它支持事件,该事件的目的是提供与文档或元素的加载状态有关的信息。事件可以用于检测是否加载完毕,当时,表示加载完成。封装事件以下,是封装事件从而达到良好的兼容性的一个简单的代码实现。 我们在开发时,经常需要检测页面是否加载完毕,以确保脚本安全运行,下面我们就来浅谈一下检测页面是否加载完毕的那些事件们。 1. onload 事件 在页面的所有资源加载完成时,window对...

    leon 评论0 收藏0
  • 2018 浅谈前端面试那些事

    摘要:声明的变量不得改变值,这意味着,一旦声明变量,就必须立即初始化,不能留到以后赋值。 虽然今年没有换工作的打算 但为了跟上时代的脚步 还是忍不住整理了一份最新前端知识点 知识点汇总 1.HTML HTML5新特性,语义化浏览器的标准模式和怪异模式xhtml和html的区别使用data-的好处meta标签canvasHTML废弃的标签IE6 bug,和一些定位写法css js放置位置和原因...

    LiuRhoRamen 评论0 收藏0
  • 2018 浅谈前端面试那些事

    摘要:声明的变量不得改变值,这意味着,一旦声明变量,就必须立即初始化,不能留到以后赋值。 虽然今年没有换工作的打算 但为了跟上时代的脚步 还是忍不住整理了一份最新前端知识点 知识点汇总 1.HTML HTML5新特性,语义化浏览器的标准模式和怪异模式xhtml和html的区别使用data-的好处meta标签canvasHTML废弃的标签IE6 bug,和一些定位写法css js放置位置和原因...

    stormgens 评论0 收藏0
  • 2018 浅谈前端面试那些事

    摘要:声明的变量不得改变值,这意味着,一旦声明变量,就必须立即初始化,不能留到以后赋值。 虽然今年没有换工作的打算 但为了跟上时代的脚步 还是忍不住整理了一份最新前端知识点 知识点汇总 1.HTML HTML5新特性,语义化浏览器的标准模式和怪异模式xhtml和html的区别使用data-的好处meta标签canvasHTML废弃的标签IE6 bug,和一些定位写法css js放置位置和原因...

    Hujiawei 评论0 收藏0
  • 浅谈网页基本性能优化规则小结

    摘要:雪碧图内联图片将站内小图标合并成一张图,使用定位截取对应图标适当使用内联图片。浏览器缓存合理设置浏览器缓存是网页优化的重要手段之一。为什么要减少请求在性能优化中减少请求的措施占了很大部分,比如使用雪碧 这篇文章主要介绍了浅谈网页基本性能优化规则小结的相关资料,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧 针对浏览器网页的一些优化规则 页面优化 静态资源压缩...

    Aomine 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<