ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

页面加载事件--DOMContentLoaded

2020-03-21 11:56:30  阅读:236  来源: 互联网

标签:onload init window DOMContentLoaded 加载 页面


DOMContentLoaded 和 window.onload 的区别

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

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

示例

<script>
  document.addEventListener("DOMContentLoaded", function(event) {
    console.log("DOM fully loaded and parsed");
  });
</script>

兼容性

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 onl oad
    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 事件并不可靠,如果页面中存在图片的时候,可能反而在 onl oad 事件之后才触发,正常来说,它只能正确地执行页面不包含二进制资源或者非常少或者被缓存为时作为一个备选方案

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);
        }
}

相关事件

拓展

本文转载于:猿2048➻https://www.mk2048.com/blog/blog.php?id=hhh2kj2c21j

标签:onload,init,window,DOMContentLoaded,加载,页面
来源: https://www.cnblogs.com/homehtml/p/12537488.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有