`
mutongwu
  • 浏览: 448367 次
  • 性别: 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
分享到:
评论

相关推荐

    各浏览器对link标签onload/onreadystatechange事件支持的差异分析

    另外,可以考虑使用`window.onload`或`DOMContentLoaded`事件来确保整个页面资源(包括外部样式表)加载完毕后再执行特定操作。 总的来说,onload和onreadystatechange事件在浏览器之间的支持并不统一,这要求...

    iframe的onreadystatechange事件在firefox下的使用

    总之,对于跨浏览器的`iframe`加载事件处理,推荐使用`onload`事件,同时考虑使用`DOMContentLoaded`或`readystatechange`(在支持的浏览器中)作为补充,以确保在不同环境下都能正确地检测到`iframe`的加载状态。...

    JavaScript的jQuery库中ready方法的学习教程

    对于不支持`DOMContentLoaded`事件的老版本IE浏览器,可以利用`onreadystatechange`事件,特别是当`document.readyState`等于`complete`时。但是,这个事件的可靠性较差,因为它可能在`onload`之后才触发,特别是...

    javascript页面加载完执行事件代码

    2. 优先考虑使用window.onload或document.addEventListener('DOMContentLoaded', function() {...})方法,而不是document.onreadystatechange,除非需要根据页面加载状态的细微变化进行处理。 3. 如果页面中有多个...

    jQuery ready方法实现原理详解

    5. 另外,对于旧版IE浏览器,存在一个问题,就是它不支持DOMContentLoaded事件,而且在iframe结构中,当iframe的源与父页面不同时,onreadystatechange事件也会触发,从而导致错误地认为DOM已经加载完成。...

    jQuery 的 ready()的纯js替代方法

    对于老版本的浏览器,可以使用`document.onreadystatechange`或`window.onload`。 ```javascript document.onreadystatechange = function() { if (document.readyState === 'complete') { // 在这里执行你的...

    让浏览器DOM元素最后加载的js方法

    正确的使用window.onload和DOMContentLoaded,可以有效地处理页面加载的顺序问题,提升用户体验。在实际开发中,建议开发者根据具体需求和浏览器兼容性,选择合适的方法来实现DOM元素的最后加载处理。

    [removed] 加载完毕的问题及解决方案(下)

    `window.onload` 是JavaScript中最常见的一个事件,用于在浏览器加载完整个页面(包括所有图像、CSS和JavaScript文件)后触发指定的函数。 然而,不同浏览器对`window.onload` 的处理方式有所不同,导致在跨浏览器...

    domReady的实现案例

    对于`<iframe>`元素,`DOMContentLoaded`和`onload`事件的触发顺序在IE和非IE浏览器中有所不同。在IE中,主页面的`DOMContentLoaded`事件会等待`iframe`加载完成后再触发,而在非IE浏览器中,`iframe`的加载是异步的...

    jQuery的ready方法详解

    对于不支持`addEventListener`的浏览器,如IE6、7、8,jQuery会使用`attachEvent`监听`onreadystatechange`事件,以及`onload`事件来确保在页面加载完成后执行代码。此外,对于低版本的IE,还有特殊处理来检测DOM...

    原生JS实现DOM加载完成马上执行JS代码的方法

    6. **兼容性处理**:为了在各种浏览器中实现兼容,可以编写一个通用函数来适配DOMContentLoaded事件和document.onreadystatechange事件。如果存在这些事件,则绑定事件处理函数;如果不存在,比如在IE浏览器中,使用...

    javascript经典特效---打开页面的等待(三).rar

    考虑到性能和浏览器兼容性,可以使用`DOMContentLoaded`事件替代`window.onload`,它在DOM解析完成时触发,不等待资源加载。如果需要兼容旧版浏览器,可以同时监听这两个事件。 7. **异步加载** 当页面有大量异步...

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

    4. bindReady函数根据当前浏览器的类型和情况,通过不同的方式绑定DOMContentLoaded或onreadystatechange事件。对于IE,利用doScroll方法检测DOM加载状态。 5. ready函数最后通过闭包的方式暴露出来,以便开发者...

    jQuery的ready方法实现原理分析

    在jQuery中,`ready`方法并不是简单的封装`window.onload`或`document.onload`事件,而是利用了标准W3C浏览器的`DOMContentLoaded`事件和针对IE浏览器的一些特定策略来确保在DOM树构建完成时执行代码,而无需等待...

    javascript IE中的DOM ready应用技巧

    // trying to always fire before onload d.onreadystatechange = function() { if (d.readyState == 'complete') { d.onreadystatechange = null; init(); } }; } ``` 在这个`IEContentLoaded`函数中,我们...

    attachEvent和addEventListener 使用方法

    window.attachEvent('onreadystatechange', function() { if (document.readyState === 'complete') { document.body.removeChild(script); } }); } ``` 以上就是关于 `attachEvent` 和 `addEventListener` 的...

    如何让动态插入的javascript脚本代码跑起来

    此外,还可以利用`onreadystatechange`事件来检测脚本加载状态,一旦`readyState`变为`complete`,则表明脚本已加载并执行完毕,此时调用函数是安全的。 总结来说,动态插入JavaScript脚本代码的关键在于确保脚本...

Global site tag (gtag.js) - Google Analytics