原生JS實現DOM載入完成馬上執行JS程式碼
用原生JS我們經常使用window.onload事件來載入頁面。但是window.onload是在頁面元素都載入完畢後才執行,如果頁面內有大的圖片的話,會在頁面展現後好久時間後才執行。所以有時我們需要在DOM載入時馬上執行一些函式。jQuery提供了document.ready方法用來代替window.onload。但又不願意僅為了這一個需求而引入整個JQuery庫,於是就把jQuery的方法提取出來,單獨使用了。
如果只需要對DOM進行操作,那麼這時就沒必要等到頁面全部載入了。Firefox有DOMContentLoaded事件可以輕鬆解決,可惜的就是IE沒有。
MSDN關於JSCRIPT的一個方法有段不起眼的話,當頁面DOM未載入完成時,呼叫doScroll方法時,會產生異常。那麼我們反過來用,如果不異常,那麼就是頁面DOM載入完畢了。所以 對於Mozilla & Opera 瀏覽器,在dom樹載入後有現成的 DOMContentLoaded 事件。對於Safari 瀏覽器,有document.onreadystatechange事件,當該觸發時,如果 document.readyState=complete時,可視為dom樹已經載入。
對於ie,當在iframe內時,同樣有document.onreadystatechange事件,對於ie在非iframe內時,只有不斷地通過能否執行doScroll判斷dom是否載入完畢。
在本例中每間隔5毫秒嘗試去執行 document.documentElement.doScroll(‘left’)。在ie8下,貌視非iframe視窗也會有 document.onreadystatechange事件,另外也可以在構建自己的框架時使用此函式。
(function(){ var isReady=false; //判斷onDOMReady方法是否已經被執行過 var readyList= [];//把需要執行的方法先暫存在這個數組裡 var timer;//定時器控制代碼 ready=function(fn) { if (isReady ) fn.call( document); else readyList.push( function() { return fn.call(this);}); return this; } var onDOMReady=function(){ for(var i=0;i< readyList.length;i++) { readyList[i].apply(document); } readyList = null; } var bindReady = function(evt) { if(isReady) return; isReady=true; onDOMReady.call(window); if(document.removeEventListener) { document.removeEventListener("DOMContentLoaded", bindReady, false); } else if(document.attachEvent) { document.detachEvent("onreadystatechange", bindReady); if(window == window.top){ clearInterval(timer);//事件發生後清除定時器 timer = null; } } }; if(document.addEventListener){ document.addEventListener("DOMContentLoaded", bindReady, false); } else if(document.attachEvent)//非最頂級父視窗 { document.attachEvent("onreadystatechange", function(){ if((/loaded|complete/).test(document.readyState)) bindReady(); }); if(window == window.top)//在應用有frameset或者iframe的頁面時,parent是父視窗,top是最頂級父視窗(有的視窗中套了好幾層frameset或者iframe) { timer = setInterval(function(){ try { isReady||document.documentElement.doScroll('left');//在IE下用能否執行doScroll判斷 dom是否載入完畢 } catch(e) { return; } bindReady(); },5); } } })();
下面是使用方法:
ready(dosomething);//dosomething為已存在的函式
//也可以通過閉包來使用
ready(function(){
//這裡是邏輯程式碼
});