如果你不考慮支援IE,現代瀏覽器為javascript添加了許多黑魔法,讓我們能寫出更強有力的代碼,如下面介紹的domReady。
function r(f){/in/(document.readyState)?setTimeout(r,0,f):f()}
需要以下知識點瞭解其運作:
- document.readyState的五種狀態,"uninitalized"、"loading"、"interactive"、"complete" 、"loaded",不過FF3.6+才開始支援此屬性。
- 死去的ecma4為正則字面量添加的新特性,讓它擁有像exec方法一樣的行為。詳見這裡
- 現代瀏覽器的setTimeout支援更多參數,第二個參數後的參數用作回呼函數的參數,見下面測試:
<br /> setTimeout(function(a,b,c){<br /> alert([a,b,c])<br /> },1000,"司徒正美","測試2","測試3")<br />運行代碼
如果你一定要支援IE,就得把此方法寫長一點:
function r(f){/in/.exec(document.readyState)?setTimeout('r('+f+')',0):f()}
或許有人會提到DOMContentLoaded事件,但那不能觸發domReady之後添加的函數。當然這個迷你的domReady的能力與它的體積相稱,不支援多投事件。要使用支援多投事件,請見我另一篇博文《我的domReady第三版》
附上其他domReady的迷你實現
//https://github.com/jed/alReady.jsalReady = function( fn ) { var add = "addEventListener" , win = this , doc = win.document , pre = doc[ add ] ? "" : "on"; /m/( doc.readyState ) ? fn() : "load DOMContentLoaded readystatechange".replace( /\w+/g, function( type, i ) { ( i ? doc : win ) [ pre ? "attachEvent" : add ] ( pre + type, function(){ if ( fn ) if ( i https://github.com/dperini/ContentLoaded/blob/master/src/contentloaded.jsfunction contentLoaded(win, fn) {var done = false, top = true,doc = win.document, root = doc.documentElement,add = doc.addEventListener ? 'addEventListener' : 'attachEvent',rem = doc.addEventListener ? 'removeEventListener' : 'detachEvent',pre = doc.addEventListener ? '' : 'on',init = function(e) {if (e.type == 'readystatechange' && doc.readyState != 'complete') return;(e.type == 'load' ? win : doc)[rem](pre + e.type, init, false);if (!done && (done = true)) fn.call(win, e.type || e);},poll = function() {try { root.doScroll('left'); } catch(e) { setTimeout(poll, 50); return; }init('poll');};if (doc.readyState == 'complete') fn.call(win, 'lazy');else {if (doc.createEventObject && root.doScroll) {try { top = !win.frameElement; } catch(e) { }if (top) poll();}doc[add](pre + 'DOMContentLoaded', init, false);doc[add](pre + 'readystatechange', init, false);win[add](pre + 'load', init, false);}}