$(document).ready equivalent without jQuery
我有一个使用
我如何在不使用jquery的情况下实现自己的
有一种基于标准的替代产品,即
1 2 3 | document.addEventListener("DOMContentLoaded", function(event) { //do work }); |
jquery的本机函数比window.onload复杂得多,如下所示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | function bindReady(){ if ( readyBound ) return; readyBound = true; // Mozilla, Opera and webkit nightlies currently support this event if ( document.addEventListener ) { // Use the handy event callback document.addEventListener("DOMContentLoaded", function(){ document.removeEventListener("DOMContentLoaded", arguments.callee, false ); jQuery.ready(); }, false ); // If IE event model is used } else if ( document.attachEvent ) { // 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(); } }); // 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(); })(); } // A fallback to window.onload, that will always work jQuery.event.add( window,"load", jQuery.ready ); } |
编辑:
这里有一个可以替代jquery的可行方案。1 2 3 4 5 6 7 8 9 10 11 12 13 14 | function ready(callback){ // in case the document is already rendered if (document.readyState!='loading') callback(); // modern browsers else if (document.addEventListener) document.addEventListener('DOMContentLoaded', callback); // IE <= 8 else document.attachEvent('onreadystatechange', function(){ if (document.readyState=='complete') callback(); }); } ready(function(){ // do something }); |
取自https://plainjs.com/javascript/events/running-code-when-the-document-is-ready-15/
另一个好的domready函数,摘自https://stackoverflow.com/a/9899701/175071
由于接受的答案还远远不够完整,我根据jquery 1.6.2源将
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 | var ready = (function(){ var readyList, DOMContentLoaded, class2type = {}; class2type["[object Boolean]"] ="boolean"; class2type["[object Number]"] ="number"; class2type["[object String]"] ="string"; class2type["[object Function]"] ="function"; class2type["[object Array]"] ="array"; class2type["[object Date]"] ="date"; class2type["[object RegExp]"] ="regexp"; class2type["[object Object]"] ="object"; var ReadyObj = { // Is the DOM ready to be used? Set to true once it occurs. isReady: false, // A counter to track how many items to wait for before // the ready event fires. See #6781 readyWait: 1, // Hold (or release) the ready event holdReady: function( hold ) { if ( hold ) { ReadyObj.readyWait++; } else { ReadyObj.ready( true ); } }, // Handle when the DOM is ready ready: function( wait ) { // Either a released hold or an DOMready/load event and not yet ready if ( (wait === true && !--ReadyObj.readyWait) || (wait !== true && !ReadyObj.isReady) ) { // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). if ( !document.body ) { return setTimeout( ReadyObj.ready, 1 ); } // Remember that the DOM is ready ReadyObj.isReady = true; // If a normal DOM Ready event fired, decrement, and wait if need be if ( wait !== true && --ReadyObj.readyWait > 0 ) { return; } // If there are functions bound, to execute readyList.resolveWith( document, [ ReadyObj ] ); // Trigger any bound ready events //if ( ReadyObj.fn.trigger ) { // ReadyObj( document ).trigger("ready" ).unbind("ready" ); //} } }, bindReady: function() { if ( readyList ) { return; } readyList = ReadyObj._Deferred(); // Catch cases where $(document).ready() is called after the // browser event has already occurred. if ( document.readyState ==="complete" ) { // Handle it asynchronously to allow scripts the opportunity to delay ready return setTimeout( ReadyObj.ready, 1 ); } // Mozilla, Opera and webkit nightlies currently support this event 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", ReadyObj.ready, false ); // If IE event model is used } else if ( document.attachEvent ) { // 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", ReadyObj.ready ); // If IE and not a frame // continually check to see if the document is ready var toplevel = false; try { toplevel = window.frameElement == null; } catch(e) {} if ( document.documentElement.doScroll && toplevel ) { doScrollCheck(); } } }, _Deferred: function() { var // callbacks list callbacks = [], // stored [ context , args ] fired, // to avoid firing when already doing so firing, // flag to know if the deferred has been cancelled cancelled, // the deferred itself deferred = { // done( f1, f2, ...) done: function() { if ( !cancelled ) { var args = arguments, i, length, elem, type, _fired; if ( fired ) { _fired = fired; fired = 0; } for ( i = 0, length = args.length; i < length; i++ ) { elem = args[ i ]; type = ReadyObj.type( elem ); if ( type ==="array" ) { deferred.done.apply( deferred, elem ); } else if ( type ==="function" ) { callbacks.push( elem ); } } if ( _fired ) { deferred.resolveWith( _fired[ 0 ], _fired[ 1 ] ); } } return this; }, // resolve with given context and args resolveWith: function( context, args ) { if ( !cancelled && !fired && !firing ) { // make sure args are available (#8421) args = args || []; firing = 1; try { while( callbacks[ 0 ] ) { callbacks.shift().apply( context, args );//shifts a callback, and applies it to document } } finally { fired = [ context, args ]; firing = 0; } } return this; }, // resolve with this as context and given arguments resolve: function() { deferred.resolveWith( this, arguments ); return this; }, // Has this deferred been resolved? isResolved: function() { return !!( firing || fired ); }, // Cancel cancel: function() { cancelled = 1; callbacks = []; return this; } }; return deferred; }, type: function( obj ) { return obj == null ? String( obj ) : class2type[ Object.prototype.toString.call(obj) ] ||"object"; } } // The DOM ready check for Internet Explorer function doScrollCheck() { if ( ReadyObj.isReady ) { return; } try { // If IE is used, use the trick by Diego Perini // http://javascript.nwbox.com/IEContentLoaded/ document.documentElement.doScroll("left"); } catch(e) { setTimeout( doScrollCheck, 1 ); return; } // and execute any waiting functions ReadyObj.ready(); } // Cleanup functions for the document ready method if ( document.addEventListener ) { DOMContentLoaded = function() { document.removeEventListener("DOMContentLoaded", DOMContentLoaded, false ); ReadyObj.ready(); }; } else if ( document.attachEvent ) { DOMContentLoaded = function() { // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). if ( document.readyState ==="complete" ) { document.detachEvent("onreadystatechange", DOMContentLoaded ); ReadyObj.ready(); } }; } function ready( fn ) { // Attach the listeners ReadyObj.bindReady(); var type = ReadyObj.type( fn ); // Add the callback readyList.done( fn );//readyList is result of _Deferred() } return ready; })(); |
如何使用:
1 2 3 4 5 6 | ready(function(){ alert('It works!'); }); ready(function(){ alert('Also works!'); }); |
我不确定这段代码的功能,但它在我的肤浅测试中工作得很好。这花了很长时间,所以我希望你和其他人能从中受益。
附:我建议编译它。
或者您可以使用http://dustiniaz.com/minister-domready-ever:
1 2 | function r(f){/in/.test(document.readyState)?setTimeout(r,9,f):f()} r(function(){/*code to run*/}); |
或者,如果只需要支持新的浏览器,则使用本机函数(与jquery ready不同,如果在页面加载后添加此函数,则不会运行此函数)
1 | document.addEventListener('DOMContentLoaded',function(){/*fun code to run*/}) |
三种选择:
OnReadyStateChange(状态更改)
1 2 3 4 5 | document.onreadystatechange = function () { if (document.readyState =="complete") { // document is ready. Do your stuff here } } |
资料来源:多媒体数字网
已加载domcontentloaded
1 2 3 | document.addEventListener('DOMContentLoaded', function() { console.log('document is ready. I can sleep now'); }); |
关注石器时代的浏览器:转到jquery源代码并使用
把你的
不可否认,这可能不适合每个人的目的,因为它需要更改HTML文件,而不仅仅是在javascript文件a la
穷人的解决方案:
1 2 3 4 5 | var checkLoad = function() { document.readyState !=="complete" ? setTimeout(checkLoad, 11) : alert("loaded!"); }; checkLoad(); |
查看小提琴
加上了这个,我想更好一点,有自己的作用域和非递归的
1 2 3 4 5 6 7 8 9 | (function(){ var tId = setInterval(function() { if (document.readyState =="complete") onComplete() }, 11); function onComplete(){ clearInterval(tId); alert("loaded!"); }; })() |
查看小提琴
我用这个:
1 2 3 | document.addEventListener("DOMContentLoaded", function(event) { //Do work }); |
注意:这可能只适用于较新的浏览器,尤其是以下浏览器:http://caniuse.com/feat=domcontentloaded
实际上,如果您只关心Internet Explorer 9+,则此代码足以取代
1 | document.addEventListener("DOMContentLoaded", callback); |
如果您担心Internet Explorer 6和一些非常奇怪和罕见的浏览器,这将起作用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | domReady: function (callback) { // Mozilla, Opera and WebKit if (document.addEventListener) { document.addEventListener("DOMContentLoaded", callback, false); // If Internet Explorer, the event model is used } else if (document.attachEvent) { document.attachEvent("onreadystatechange", function() { if (document.readyState ==="complete" ) { callback(); } }); // A fallback to window.onload, that will always work } else { var oldOnload = window.onload; window.onload = function () { oldOnload && oldOnload(); callback(); } } }, |
这个问题很久以前就被问到了。对于任何刚刚看到这个问题的人来说,现在有一个名为"你可能不需要jquery"的网站,它按所需的IE支持级别分解了jquery的所有功能,并提供了一些替代的、较小的库。
IE8文档就绪脚本根据您可能不需要jquery
1 2 3 4 5 6 7 8 9 10 11 | function ready(fn) { if (document.readyState != 'loading') fn(); else if (document.addEventListener) document.addEventListener('DOMContentLoaded', fn); else document.attachEvent('onreadystatechange', function() { if (document.readyState != 'loading') fn(); }); } |
我最近用这个做手机网站。这是John Resig从"pro-javascript技术"得到的简化版本。这取决于addevent。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | var ready = ( function () { function ready( f ) { if( ready.done ) return f(); if( ready.timer ) { ready.ready.push(f); } else { addEvent( window,"load", isDOMReady ); ready.ready = [ f ]; ready.timer = setInterval(isDOMReady, 13); } }; function isDOMReady() { if( ready.done ) return false; if( document && document.getElementsByTagName && document.getElementById && document.body ) { clearInterval( ready.timer ); ready.timer = null; for( var i = 0; i < ready.ready.length; i++ ) { ready.ready[i](); } ready.ready = null; ready.done = true; } } return ready; })(); |
jquery的答案对我很有用。只要稍加重构,它就很适合我的需要。我希望它能帮助任何人。
1 2 3 4 5 6 7 8 9 10 | function onReady ( callback ){ var addListener = document.addEventListener || document.attachEvent, removeListener = document.removeEventListener || document.detachEvent eventName = document.addEventListener ?"DOMContentLoaded" :"onreadystatechange" addListener.call(document, eventName, function(){ removeListener( eventName, arguments.callee, false ) callback() }, false ) } |
跨浏览器(也是旧浏览器)和一个简单的解决方案:
1 2 3 4 5 6 7 8 | var docLoaded = setInterval(function () { if(document.readyState !=="complete") return; clearInterval(docLoaded); /* Your code goes here i.e. init() */ }, 30); |
在jsFiddle中显示警报
下面是测试DOM就绪的最小代码片段,它适用于所有浏览器(甚至是IE 8):
1 2 3 4 | r(function(){ alert('DOM Ready!'); }); function r(f){/in/.test(document.readyState)?setTimeout('r('+f+')',9):f()} |
看看这个答案。
只需将它添加到HTML页面的底部…
1 | Your_Function(); |
因为,HTML文档是由顶部和底部来解析的。
值得一看Rock Solid AddEvent()和http://www.braksator.com/how-to-make-your-own-jquery。
这是万一网站瘫痪的代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | function addEvent(obj, type, fn) { if (obj.addEventListener) { obj.addEventListener(type, fn, false); EventCache.add(obj, type, fn); } else if (obj.attachEvent) { obj["e"+type+fn] = fn; obj[type+fn] = function() { obj["e"+type+fn]( window.event ); } obj.attachEvent("on"+type, obj[type+fn] ); EventCache.add(obj, type, fn); } else { obj["on"+type] = obj["e"+type+fn]; } } var EventCache = function(){ var listEvents = []; return { listEvents : listEvents, add : function(node, sEventName, fHandler){ listEvents.push(arguments); }, flush : function(){ var i, item; for(i = listEvents.length - 1; i >= 0; i = i - 1){ item = listEvents[i]; if(item[0].removeEventListener){ item[0].removeEventListener(item[1], item[2], item[3]); }; if(item[1].substring(0, 2) !="on"){ item[1] ="on" + item[1]; }; if(item[0].detachEvent){ item[0].detachEvent(item[1], item[2]); }; item[0][item[1]] = null; }; } }; }(); // Usage addEvent(window, 'unload', EventCache.flush); addEvent(window, 'load', function(){alert("I'm ready");}); |
此跨浏览器代码将在DOM就绪后调用函数:
1 2 3 4 5 6 | var domReady=function(func){ var scriptText='('+func+')();'; var scriptElement=document.createElement('script'); scriptElement.innerText=scriptText; document.body.appendChild(scriptElement); }; |
工作原理如下:
例如,如果您这样做:
1 | (function (){alert();})(); |
注意,这只适用于用户定义的函数。以下内容不起作用:
与jquery相比,使用JavaScript等价物总是很好的。一个原因是需要依赖的库少了一个,而且它们比jquery等价物快得多。
jquery等价物的一个很好的参考是http://youmighttnotneedjquery.com/。
关于您的问题,我从上面的链接中获取了以下代码:)唯一需要注意的是,它只适用于Internet Explorer 9及更高版本。
1 2 3 4 5 6 7 8 | function ready(fn) { if (document.readyState != 'loading') { fn(); } else { document.addEventListener('DOMContentLoaded', fn); } } |
这个解决方案怎么样?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | // other onload attached earlier window.onload=function() { ; }; tmpPreviousFunction=window.onload ? window.onload : null; // our onload function window.onload=function() { alert('another message'); // execute previous one if (tmpPreviousFunction) tmpPreviousFunction(); }; |
我们发现了一个快速而肮脏的跨浏览器实现,它可以在实现最少的情况下为大多数简单的情况提供帮助:
1 2 3 | window.onReady = function onReady(fn){ document.body ? fn() : setTimeout(function(){ onReady(fn);},50); }; |
这里介绍的setTimeout/setInterval解决方案只能在特定情况下工作。
这个问题尤其出现在旧版本的Internet Explorer(最多8个)中。
影响这些设置超时/设置间隔解决方案成功的变量有:
1 2 3 4 | 1) dynamic or static HTML 2) cached or non cached requests 3) size of the complete HTML document 4) chunked or non chunked transfer encoding |
解决此特定问题的原始(本机javascript)代码如下:
1 2 | https://github.com/dperini/ContentLoaded http://javascript.nwbox.com/ContentLoaded (test) |
这是jquery团队从中构建实现的代码。
这是我使用的,它很快,涵盖了我认为的所有基础;适用于除IE<9以外的所有事物。
1 2 3 4 5 6 7 | (() => { function fn() { //"On document ready" commands: console.log(document.readyState); }; if (document.readyState != 'loading') {fn()} else {document.addEventListener('DOMContentLoaded', fn)} })(); |
这似乎适用于所有情况:
- 如果DOM已经准备好,则立即激发(如果DOM不是"正在加载",而是"交互式"或"完成")。
- 如果DOM仍在加载,它将为当DOM可用(交互式)。
domcontentloaded事件在IE9和其他所有工具中都可用,所以我个人认为可以使用它。如果您没有将代码从ES2015发送到ES5,请将arrow函数声明重写为常规匿名函数。
如果要等到加载完所有资产、显示的所有图像等,请改用window.onload。
如果您不必支持非常老的浏览器,下面是一种方法,即使外部脚本加载了异步属性:
1 2 3 4 5 6 7 8 9 10 11 12 | HTMLDocument.prototype.ready = new Promise(function(resolve) { if(document.readyState !="loading") resolve(); else document.addEventListener("DOMContentLoaded", function() { resolve(); }); }); document.ready.then(function() { console.log("document.ready"); }); |
我简单地使用:
1 2 3 | setTimeout(function(){ //reference/manipulate DOM here }); |
与最上面的答案中的
例如,转到https://netrenderer.com/index.php,从下拉列表中选择Internet Explorer 9,输入https://dexygen.github.io/blog/oct-2017/jekyll/jekyll-categories/liquid-templates/2017/10/22/how-jekyll-builds-site-categories.html并单击"render",您将看到类似于此文章底部屏幕截图的内容。
请看下面的javascript代码,我在标题中使用它来操纵Jekyll"hacker"主题的风格,我很喜欢——特别是你可以参考
有趣的是,我在2009年偶然发现了这个
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | setTimeout(function() {//delay execution until after dom is parsed var containerEls = document.getElementsByClassName('container'); var headingEl = containerEls[0].getElementsByTagName('h1')[0]; var headerEl = document.getElementsByTagName('header')[0]; var downloadsSectionEl = document.getElementById('downloads'); var rootPath ="/"; var blogRootPath ="/blog/"; containerEls[0].style.maxWidth = '800px'; containerEls[1].style.maxWidth = '800px'; headingEl.style.margin = '0'; headerEl.style.marginBottom = '7px'; downloadsSectionEl.style.margin = '0'; if (location.pathname !== rootPath) { downloadsSectionEl.appendChild(generateNavLink('Home', rootPath)); if (location.pathname !== blogRootPath) { downloadsSectionEl.appendChild(document.createTextNode(' | ')); downloadsSectionEl.appendChild(generateNavLink('Blog Home', blogRootPath)); } } function generateNavLink(linkText, hrefPath) { var navLink = document.createElement('a'); var linkTextNode = document.createTextNode(linkText); navLink.setAttribute('href', hrefPath); navLink.appendChild(linkTextNode); return navLink; } }); |
不管怎样,在这里发布它没有什么意义,只需打开
它首先根据事件模型调用
如果您加载的jquery靠近主体底部,但在编写jquery(
与其重新创建自己的文档就绪函数,不如简单地保留函数,直到jquery可用,然后按预期继续jquery。将jquery移动到body底部的目的是加快页面加载速度,并且您仍然可以通过在模板头部嵌入jqshim.min.js来完成它。
最后我编写了这段代码,把WordPress中的所有脚本都移到了页脚,现在这个填充代码就直接位于页眉中。
大多数普通的JS就绪函数不考虑文档加载后设置
以下代码仅在文档的
1 2 3 4 5 6 | var DOMReady = function(callback) { document.readyState ==="interactive" || document.readyState ==="complete" ? callback() : document.addEventListener("DOMContentLoaded", callback()); }; DOMReady(function() { //DOM ready! }); |
如果您还想支持IE:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | var DOMReady = function(callback) { if (document.readyState ==="interactive" || document.readyState ==="complete") { callback(); } else if (document.addEventListener) { document.addEventListener('DOMContentLoaded', callback()); } else if (document.attachEvent) { document.attachEvent('onreadystatechange', function() { if (document.readyState != 'loading') { callback(); } }); } }; DOMReady(function() { // DOM ready! }); |
对于IE9+:
1 2 3 4 5 6 7 | function ready(fn) { if (document.readyState != 'loading'){ fn(); } else { document.addEventListener('DOMContentLoaded', fn); } } |
这种方法是我能想到的最短的方法。
基于domcontentloaded事件的解决方案仅在脚本在文档之前加载时才起作用,而这里建议的惰性检查确保代码始终执行,即使在稍后动态加载的脚本中,也与jquery的文档完全相同。
此代码与所有浏览器都兼容(包括一些传统浏览器,直至IE6和Safari for Windows)。
1 2 3 4 | (function ready() { if (!document.body) {setTimeout(ready, 50); return;} // Document is ready here })(); |
1 2 3 4 5 6 7 | function onDocReady(fn){ $d.readyState!=="loading" ? fn():document.addEventListener('DOMContentLoaded',fn); } function onWinLoad(fn){ $d.readyState==="complete") ? fn(): window.addEventListener('load',fn); } |
当HTML DOM准备好完全访问/分析/操作时,OnDocReady提供回调。
OnWinLoad在加载所有内容(图像等)时提供回调
- 您可以随时调用这些函数。
- 支持多个"监听器"。
- 可以在任何浏览器中使用。
试试这个:
1 2 3 4 5 6 7 8 9 10 11 | function ready(callback){ if(typeof callback ==="function"){ document.addEventListener("DOMContentLoaded", callback); window.addEventListener("load", callback); }else{ throw new Error("Sorry, I can not run this!"); } } ready(function(){ console.log("It worked!"); }); |
1 2 3 4 5 6 | (function(f){ if(document.readyState !="loading") f(); else document.addEventListener("DOMContentLoaded", f); })(function(){ console.log("The Document is ready"); }); |
这是一个很好的https://stackoverflow.com/a/11810957/185565穷人的解决方案。一条评论认为这是紧急情况下的紧急救援措施。这是我的修改。
1 2 3 4 5 6 7 8 9 10 11 12 13 | function doTheMagic(counter) { alert("It worked on" + counter); } // wait for document ready then call handler function var checkLoad = function(counter) { counter++; if (document.readyState !="complete" && counter<1000) { var fn = function() { checkLoad(counter); }; setTimeout(fn,10); } else doTheMagic(counter); }; checkLoad(0); |
编辑@duskwuff以支持Internet Explorer 8。不同之处在于对regex的函数测试和具有匿名函数的setTimeout的新调用。
另外,我将超时设置为99。
1 | function ready(f){/in/.test(document.readyState)?setTimeout(function(){ready(f);},99):f();} |
简而言之,我们可以使用javascript方法来代替jquery中使用的$(document).ready():
1 2 3 4 | document.addEventListener("DOMContentLoaded", function_name, false); function function_name(){ statements; } |
因此,当页面准备就绪(即仅加载domcontentloaded)时,将调用函数_name()。
如果您想支持Internet Explorer 7+(没有怪癖、兼容性和其他问题)、Last Chrome、Last Safari、Last FireFox和No IFrames,这就足够了:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | is_loaded = false callbacks = [] loaded = -> is_loaded = true for i in [0...callbacks.length] callbacks[i].call document callbacks = [] content_loaded = -> document.removeEventListener"DOMContentLoaded", content_loaded, true loaded() state_changed = -> if document.readyState is"complete" document.detachEvent"onreadystatechange", state_changed loaded() if !!document.addEventListener document.addEventListener"DOMContentLoaded", content_loaded, true else document.attachEvent"onreadystatechange", state_changed dom_ready = (callback) -> if is_loaded callback.call document else callbacks.push callback |