模拟兼容性的 addDOMLoadEvent 事件
2014-03-08 00:28
357 查看
模拟兼容性的 addDOMLoadEvent 事件
由于 window.onload事件需要在页面所有内容(包括图片等)加载完后,才执行,但往往我们更希望在
DOM 一加载完就执行脚本。其实在现在大部分主流浏览器上(Firefox 3+,Opera 9+,Safari 3+,Chrome 2+)都提供了这一事件方法:
addDOMLoadEvent。
document.addEventListener("DOMContentLoaded", init, false);
那对于 IE 我们如何模拟 addDOMLoadEvent 事件呢?
Matthias Miller 最早提供了如下的解决方案:
// for Internet Explorer (using conditional comments) /*@cc_on @*/ /*@if (@_win32) document.write("<script id=__ie_onload defer src=javascript:void(0)><\/script>"); var script = document.getElementById("__ie_onload"); script.onreadystatechange = function() { if (this.readyState == "complete") { init(); // call the onload handler } }; /*@end @*/
而 Diego Perini 在其后提供了一种利用
doScroll()方法来模拟
addDOMLoadEvent 事件的方案,且现在主流的 JavaScript 框架(JQuery、YUI等)基本都采用的这一解决方案。
原理基本如下:
当 ondocumentready 事件触发,文档( document )已经完全解析和建立。如果组件需要操作最初的文档结构,初始化代码需被安置在这之后。ondocumentready 事件告知组件,整个页面已被加载,且在 初始文档的 onload 事件触发之前立即触发。
一些方法,例如 doScroll,要求最初的文档被完全加载。如果这些方法是初始化函数的一部分,当ondocumentready 事件触发,他们将被执行。
/* * * IEContentLoaded.js * * Author: Diego Perini (diego.perini at gmail.com) NWBOX S.r.l. * Summary: DOMContentLoaded emulation for IE browsers * Updated: 05/10/2007 * License: GPL/CC * Version: TBD * */ // @w window reference // @fn function reference 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(); } }; }
JQuery 1.3.2 中源码实现如下:
// If IE and not an iframe // continually check to see if the document is ready if ( document.documentElement.doScroll && window == window.top ) (function(){ if ( jQuery.isReady ) return; try { // If IE is used, use the trick by Diego Perini // http://javascript.nwbox.com/IEContentLoaded/ document.documentElement.doScroll("left"); } catch( error ) { setTimeout( arguments.callee, 0 ); return; } // and execute any waiting functions jQuery.ready(); })();
YUI 2.7.0 中源码实现如下:
if (EU.isIE) { // Process onAvailable/onContentReady items when the // DOM is ready. YAHOO.util.Event.onDOMReady( YAHOO.util.Event._tryPreloadAttach, YAHOO.util.Event, true); var n = document.createElement('p'); EU._dri = setInterval(function() { try { // throws an error if doc is not ready n.doScroll('left'); clearInterval(EU._dri); EU._dri = null; EU._ready(); n = null; } catch (ex) { } }, EU.POLL_INTERVAL); }
另外对于版本小于 Safari 3+ 的 Safari 浏览器,John Resig 也提供了一个解决方案:
if (/WebKit/i.test(navigator.userAgent)) { // sniff var _timer = setInterval(function() { if (/loaded|complete/.test(document.readyState)) { clearInterval(_timer); init(); // call the onload handler } }, 10); }
怿飞提示:
如果脚本是动态注入到页面上,则原生的 DOMContentReady 事件是不会被触发(即:IE 除外)。
IE 下对于在 iframe 里的使用 addDOMLoadEvent 事件,需做处理和慎用(这一点 YUI 做得不如 JQuery 细致)。
// form JQuery 1.3.2 // ensure firing before onload, maybe late but safe also for iframes document.attachEvent("onreadystatechange", function(){ if ( document.readyState === "complete" ) { document.detachEvent( "onreadystatechange", arguments.callee ); jQuery.ready(); } });
相关文章推荐
- 模拟兼容性的 addDOMLoadEvent 事件
- 模拟兼容性的 addDOMLoadEvent 事件
- IE模拟addDOMLoadEvent和jQuery的ready实现
- [JavaScript]addDOMLoadEvent:DOM加载事件
- 共享 load事件--addLoadEvent
- 整理浏览器对网页的兼容性问题-DOM事件(event)的使用
- addLoadEvent:共享onload事件。
- addLoadEvent:共享onload事件。
- javascript 事件队列加载函数 addLoadEvent
- javascript 事件队列加载函数 addLoadEvent
- Jquery的ready实现addDOMLoadEvent [转]
- DOM编程艺术推荐的addLoadEvent和insertAfter
- addLoadEvent(func):把多个javascript函数绑定到onload事件
- [JavaScript]addLoadEvent方法--摘自<JavaScript+DOM编程艺术>
- Jquery的ready实现addDOMLoadEvent
- addLoadEvent函数将多个事件添加到window.onload
- addLoadEvent(func):把多个javascript函数绑定到onload事件
- 【DOM编程艺术】window.onload延伸addLoadEvent
- LOAD_DLL_DEBUG_EVENT调试事件
- addLoadEvent