资讯专栏INFORMATION COLUMN

页面加载事件--DOMContentLoaded

jkyin / 3145人阅读

摘要:这个时候就出场了,它定义为当页面文档加载并解析完毕之后会马上出发事件,而不会等待样式文件图片文件和子框架页面的加载。

DOMContentLoaded 和 window.onload 的区别

当页面完全加载完毕后会触发 window.onload 事件,我们知道可以利用 window.onload 事件来触发并执行需要页面完全加载完毕后才能执行的 javascript 脚本,但是假如页面包含很多样式文件、图片文件、子框架页面(iframe)的话,onload 事件也会被相应延迟到这些文件加载完成才执行,有时候并不是我们所需要的,例如我们想知道页面从接受完毕到 dom 树解析完成所需要的时间,那么 onload 事件则不适合了。

这个时候 DOMContentLoaded 就出场了,它定义为: 当页面文档加载并解析完毕之后会马上出发 DOMContentLoaded 事件,而不会等待样式文件、图片文件和子框架页面的加载。

示例
兼容性

DOMContentLoaded 目前支持所有主流浏览器,IE9 之后也支持, 更多请看can I use?

如果要兼容 IE,则需要额外两个事件,在 IE8 中,可以使用 readystatechange 事件来监测 DOM 文档是否加载完毕,在更早的 IE 版本可以通过每隔一段时间用 try/catch 执行一次 document.documentElement.doScroll("left") 来监测这一状态, 因为这条代码在 DOM 加载执行完毕之前会抛出错误(throw an error)

根据以上的解释,我们可以写一个兼容 IE 的 DOMContentLoaded 事件from

// if IE
function IEContentLoaded (w, fn) {
    var d = w.document, done = false,
    // only fire once
    init = function () {
        if (!done) {
            done = true;
            fn();
        }
    };
    // polling for no errors
    (function () {
        try {
            // throws errors until after ondocumentready
            d.documentElement.doScroll("left");
        } catch (e) {
            setTimeout(arguments.callee, 50);
            return;
        }
        // no errors, fire
        init();
    })();
    // trying to always fire before onload
    d.onreadystatechange = function() {
        if (d.readyState == "complete") {
            d.onreadystatechange = null;
            init();
        }
    };
}
实验分割线

目前很多库都实现了兼容性的页面加载完成事件,大概思路是先判断 document.readyState === "complete" 是否为真,如果为真则直接执行脚本,否则才将脚本绑定到页面加载完成的事件,然后根据 document 是否有 addEventListener 来区分主流浏览器和 IE 浏览器,因为 IE9 及以后基本和主流浏览器一样的标准,所以主要用来区分 IE8 及以下,对于主流浏览器采用 DOMContentLoaded + window.load, 对于 IE8 及以下,采用 onreadystatechange + window.onload + doScroll。

这里要注意, onreadstatechange 事件并不可靠,如果页面中存在图片的时候,可能反而在 onload 事件之后才触发,正常来说,它只能正确地执行页面不包含二进制资源或者非常少或者被缓存为时作为一个备选方案

function domReady(fn) {
    var ready = false,
        top = false,
        doc = window.document,
        root = doc.documentElement,
        modern = doc.addEventListener,
        add = modern ? "addEventListener" : "attachEvent",
        del = modern ? "removeEventListener" : "detachEvent",
        pre = modern ? "" : "on",
        init = function(e) {
            if (e.type === "readystatechange" && doc.readyState !== "complete") return;
            (e.type === "load" ? window : doc)[del](pre + e.type, init, false);
            if (!ready && (ready = true)) fn.call(window, e.type || e);
        },
        poll = function() {
            try {
                root.doScroll("left");
            } catch(e) {
                setTimeout(pull, 50);
                return;
            }
            init("poll");
        };
        
        if (doc.readyState === "complete") fn.call(window, "lazy");
        else {
            if (!modern && root.doScroll) {
                try {
                    top = !window.frameElement;
                } catch(e) {}
                if (top) poll();
            }
            doc[add](pre + "DOMContentLoaded", init, false);
            doc[add](pre + "readystatechange", init, false);
            window[add](pre + "load", init, false);
        }
}
相关事件

readystatechange

load

beforeunload

unload

拓展

jquery ready 分析

ContentedLoaded

关于DOMReady的IE兼容实现,为什么说有了doScroll之后更接近DOMContentLoaded

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

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

相关文章

  • 页面生命周期:DOMContentLoaded, load, beforeunload, unloa

    摘要:所以有可能在所有脚本执行完毕后触发。如果用户即将离开页面或者关闭窗口时,事件将会被触发以进行额外的确认。状态表示事件即将被触发。总结页面事件的生命周期事件在树构建完毕后被触发,我们可以在这个阶段使用去访问元素。 页面生命周期:DOMContentLoaded, load, beforeunload, unload 原文地址:http://javascript.info/onload.....

    lx1036 评论0 收藏0
  • 页面生命周期:DOMContentLoaded, load, beforeunload, unloa

    摘要:所以有可能在所有脚本执行完毕后触发。如果用户即将离开页面或者关闭窗口时,事件将会被触发以进行额外的确认。状态表示事件即将被触发。总结页面事件的生命周期事件在树构建完毕后被触发,我们可以在这个阶段使用去访问元素。 页面生命周期:DOMContentLoaded, load, beforeunload, unload 原文地址:http://javascript.info/onload.....

    luckyyulin 评论0 收藏0
  • 浅谈DOMContentLoaded事件及其封装方法

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

    waruqi 评论0 收藏0
  • 浅谈DOMContentLoaded事件及其封装方法

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

    leon 评论0 收藏0
  • 前端优化-Javascript篇(2.异步加载脚本)

    摘要:下面介绍非阻塞加载脚本技术也就是异步加载。非阻塞加载脚本关于的一篇好文目前所有浏览器都支持属性,但是和中只有在加载外部脚本时才会生效,行内脚本使用是没有作用的。在中,只有外部脚本才会发生阻塞。   上篇博客说过脚本后置可以使页面更快的加载,可是这样的优化还是有限的,如果脚本需要执行一个耗时的操作,就算后置了它还是会阻塞后续脚本加载和执行并且阻塞整个页面。下面介绍非阻塞加载脚本技术也就是...

    wpw 评论0 收藏0
  • WEB页面的生命周期,DOMContentLoaded,load,beforeunload,unlo

    摘要:简言理解页面的生命周期,文档加载事件及顺序对开发有十分的重要意义。同步的脚本最先执行,它先于事件执行。当准备就绪时,事件在上触发。表示文档的当前状态,可以在事件中跟踪文档状态的变更。已经解析完毕时触发,几乎与同时发生,但在事件之前触发。 简言 理解WEB页面的生命周期,文档加载事件及顺序对WEB开发有十分的重要意义。如果不理解,在元素未加载就提前操作元素,则得不到想要的结果。而如果页面...

    Jingbin_ 评论0 收藏0

发表评论

0条评论

jkyin

|高级讲师

TA的文章

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