`
mutongwu
  • 浏览: 438975 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

DOMContentLoaded VS onload VS onreadystatechange

阅读更多
1. DOMContentLoaded 在页面html、script、style加载完毕即可触发,无需等待所有资源(image/iframe)加载完毕。(IE9+)

2. onload是最早支持的事件,要求所有资源加载完毕触发。

3. onreadystatechange 开始在IE引入,后来其它浏览器也有一定的实现。涉及以下 document , applet, embed, frame, frameset, iframe, img, input:image, link, script, xml
标签的元素,都触发该事件。通常来讲,会有 loading /interactive/complete几个状态值。
对于页面加载完毕,检测的是 document.readystate === "complete" 状态。就目前IE6~8的测试结果来看,这个事件的触发约等同于 onload 事件,触发顺序上onload在后面。

其它需要注意的是:
1. IE11+,对于script标签,onreadystatechange不再受支持,请用onload来判断js的加载完成。
(查看;https://msdn.microsoft.com/en-us/library/ms536957(v=vs.85).aspx)



2. 在IE中,document.readystate === "interactive" ,在图片、js加载完成之前就已经触发,所以不能用来模拟 DOMContentLoaded 事件。
	// 模拟DOMContentLoaded ------- 不要这样用,这是错误的。
	document.onreadystatechange = function () {
	  if (document.readyState == "interactive") {
	    initApplication();
	  }
	}

(示例代码源自:https://developer.mozilla.org/zh-CN/docs/Web/API/Document/readyState 。)


3. 如果你在onload的事件函数里面,再次监听 onload事件,那么,是不会再次触发函数的。
	function addOnload(callback) {
	    if ( "undefined" != typeof(window.attachEvent) ) {
	        return window.attachEvent("onload", callback);
	    }
	    else if ( window.addEventListener ){
	        return window.addEventListener("load", callback, false);
	    }
	}

	function onload1() {
	    document.getElementById('results').innerHTML += "First onload executed.";
	    
		//没用的,onload2是不会被调用的.
	    addOnload(onload2);
	}

	function onload2() {
	    document.getElementById('results').innerHTML += "Second onload executed.";
	}

	addOnload(onload1);

(查看:http://www.stevesouders.com/blog/2014/09/12/onload-in-onload/)
因此,对于异步加载的JS,为了保证js能在onload里面触发,可以先判断 document.readystate === "complete",如果成功,则立即执行函数。

4. 最后,看看jQuery1.8里面,有关 ready 函数的实现:

 // The ready event handler and self cleanup method
    DOMContentLoaded = function() {
        if ( document.addEventListener ) {
            document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
            jQuery.ready();
        } else if ( document.readyState === "complete" ) {
            // we're here because readyState === "complete" in oldIE
            // which is good enough for us to call the dom ready!
            document.detachEvent( "onreadystatechange", DOMContentLoaded );
            jQuery.ready();
        }
    },

////////////////////////////////////////////////

jQuery.ready.promise = function( obj ) {
    if ( !readyList ) {

        readyList = jQuery.Deferred();

        // Catch cases where $(document).ready() is called after the
        // browser event has already occurred.
        if ( document.readyState === "complete" || ( document.readyState !== "loading" && document.addEventListener ) ) {
            // Handle it asynchronously to allow scripts the opportunity to delay ready
            setTimeout( jQuery.ready, 1 );

        // Standards-based browsers support DOMContentLoaded
        } else if ( document.addEventListener ) {
            // Use the handy event callback
            document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );

            // A fallback to window.onload, that will always work
            window.addEventListener( "load", jQuery.ready, false );

        // If IE event model is used
        } else {
            // Ensure firing before onload, maybe late but safe also for iframes
            document.attachEvent( "onreadystatechange", DOMContentLoaded );

            // A fallback to window.onload, that will always work
            window.attachEvent( "onload", jQuery.ready );

            // If IE and not a frame
            // continually check to see if the document is ready
            var top = false;

            try {
                top = window.frameElement == null && document.documentElement;
            } catch(e) {}

            if ( top && top.doScroll ) {
                (function doScrollCheck() {
                    if ( !jQuery.isReady ) {

                        try {
                            // Use the trick by Diego Perini
                            // http://javascript.nwbox.com/IEContentLoaded/
                            top.doScroll("left");
                        } catch(e) {
                            return setTimeout( doScrollCheck, 50 );
                        }

                        // and execute any waiting functions
                        jQuery.ready();
                    }
                })();
            }
        }
    }
    return readyList.promise( obj );
};




https://msdn.microsoft.com/en-us/library/ms536957(v=vs.85).aspx
https://github.com/dperini/ContentLoaded/blob/master/src/contentloaded.js
https://developer.mozilla.org/zh-CN/docs/Web/API/Document/readyState
http://www.stevesouders.com/blog/2014/09/12/onload-in-onload/
0
0
分享到:
评论

相关推荐

    Javascript封装DOMContentLoaded事件实例

    主要介绍了Javascript封装DOMContentLoaded事件实例,DOMContentLoaded是FF,Opera 9的特有的Event, 当所有DOM解析完以后会触发这个事件,需要的朋友可以参考下

    JS兼容所有浏览器的DOMContentLoaded事件

    主要介绍了JS兼容所有浏览器的DOMContentLoaded事件的相关资料,标准浏览器中,使用DOMContentLoaded事件即可实现我们的要求,注册事件处理函数也极为简单,感兴趣的朋友一起学习吧

    domloaded检查何时加载DOM类似于DOMContentLoaded

    dom-loaded 检查何时加载DOM类似于`DOMContentLoaded`

    littlepjs-document-onload-dc-web-120919

    了解DOMContentLoaded为什么如此重要 在DOMContentLoaded上设置一个事件 介绍 使用JavaScript的重要部分是确保您的代码在正确的时间运行。 有时您可能不得不添加一些额外的代码,以确保您的代码在页面准备就绪之前...

    somepjs-document-onload-dc-web-102819

    了解DOMContentLoaded为什么如此重要 在DOMContentLoaded上设置一个事件 介绍 使用JavaScript的重要部分是确保您的代码在正确的时间运行。 有时您可能不得不添加一些额外的代码,以确保您的代码在页面准备就绪之前...

    fewpjs-document-onload-rcdd_202104_tur_few

    了解DOMContentLoaded为什么如此重要 在DOMContentLoaded上设置一个事件 介绍 使用JavaScript的重要部分是确保您的代码在正确的时间运行。 有时您可能不得不添加一些额外的代码,以确保您的代码在页面准备就绪之前...

    JS、CSS以及img对DOMContentLoaded事件的影响

    最近在做性能有关的数据上报,发现了两个非常有意思的东西:Chrome开发者工具的Timeline分析面板,以及DOMContentLoaded事件。一个是强大的令人发指的性能分析工具,一个是重要的性能指标,于是就用Timeline对...

    WEB页面性能测试专业术语+页面性能测试指标采集方式

    LCP)、可交互时间(Time to Interactive,TTI)、DCL(DOMContentLoaded)、L(Onload)、界面显示速度 SI(Speed Index)、TBT(Total Blocking Time)【总阻塞时间】、FPS、CLS(Cumulative Layout Shift)【累积布局...

    dom-loaded:检查DOM是否已像DOMContentLoaded一样加载

    加载了dom 检查DOM是否已像一样加载与DOMContentLoaded不同,这在加载DOM之后包含在内时也适用。安装$ npm install dom-loaded用法import domLoaded from 'dom-loaded' ;await domLoaded ;console . log ( 'The DOM ...

    基于javascript原生判断DOM是否加载完毕

    当 DOMContentLoaded事件触发时,仅当DOM加载完成,不包括样式表,图片,flash onload 当 onload 事件触发时,页面上所有的DOM,样式表,脚本,图片,flash都已经加载完成了 根据执行时DOM是否已经装载完毕来决定是...

    Layar网络绩效预算「Layar Web Performance Budget」-crx插件

    用预算功能显示web性能的扩展(速度索引,DOMContentLoaded,时间到第一个字节) “ Layar Performance”预算会显示具有预算功能的网站性能(RUM速度指数,DOMContentLoaded和TTFB)。 此扩展将在您开发网站时为您提供...

    JS DOMReady事件的六种实现方法总结

    为了解决这个问题,ff中便增加了一个DOMContentLoaded方法,与onload相比,该方法触发的时间更早,它是在页面的DOM内容加载完成后即触发,而无需等待其他资源的加载。 Webkit引擎从版本525(Webkit nightly 1/2008

    一些主流JS框架中DOMReady事件的实现小结

    为了解决这个问题,ff中便增加了一个DOMContentLoaded方法,与onload相比,该 方法触发的时间更早,它是在页面的DOM内容加载完成后即触发,而无需等待其他资源的加载。Webkit引擎从版本525(Webkit nightly 1/2008:...

    async与defer的区别

    async是异步执行,异步下载完毕后就会执行,不确保执行顺序,一定在 onload前,但不确定在 DOMContentLoaded事件的前或后 defer是延迟执行,在浏览器看起来的效果像是将脚本放在了 body后面一样(虽然按规范应该是在...

    jQuery的ready方法详解

    jQuery中的ready方法实现了当页面加载完成后才执行的效果,但他并不是[removed]或者doucment.onload的封装,而是使用 标准W3C浏览器DOM隐藏api和IE浏览器缺陷来完成的,首先,我们来看jQuery的代码 代码如下: ...

    提取jquery的ready()方法单独使用示例

    大家可以使用windows.onload事件,但onload在看来,就是页面上的东西(img,iframe等资源)全部都加载完毕后才能发生,如果页面内有大的图片的话,会在页面展现后好久时间后才执行。 如果只需要对DOM进行操作,那么...

Global site tag (gtag.js) - Google Analytics