1. 程式人生 > >原生JS實現DOM載入完成馬上執行JS程式碼

原生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(){
     //這裡是邏輯程式碼
 });