js實現類型jq的dom加載完成


有時候我們只想在 dom 加載完成后運行 js ,而不是等所有圖片加載完成。所以不需要 onload , onload 會加載圖片等其他媒體。很消耗時間。

原:http://blog.csdn.net/shoushou71/article/details/52252340

 

前沿
處理頁面文檔加載的時候,我們遇到一個難題,就是使用window.onload這種將所有內容加載后(包括DOM文檔結構,外部腳本、樣式,圖片音樂等)這樣會導致在長時間加載頁面的情況下,js程序是不可用的狀態。而JS其實只需要HTML DOM文檔結構構造完畢之后就可以使用了,沒必要等待諸如圖片音樂和外部內容加載。


一.問題所在

首先了解一下瀏覽器加載的順序:

1.HTML解析完畢;

2.外部腳本和樣式加載完畢;

3.腳本在文檔內解析並執行;

4.HTML DOM完全構造起來;

5.圖片和外部內容加載;

6.網頁完成加載。

 

PS:這里要了解一個問題,1-4的加載是極快的,一剎那而已。而第5條,根據網速和內容的多少各有快慢,但總體上如果有圖片和外部內容的話,比1-4條加起來都要慢很多。

PS:並且JS的document.getElementById這些只需要1-4條加載完畢后方可執行,並不需要加載第5條,所以,我們需要一種可以代替window.onload的更加快捷的加載方案。

前台測試代碼:

``` html
  <body>  
  <div id="box">box</div>  
  <img  
  src="http://h.hiphotos.baidu.com/album/s%3D1600%3Bq%3D100/sign=0686e4a05982b2b7a39f3  
  dc2019df09e/d01373f082025aaf03cd026ffbedab64024f1a92.jpg"></img  
    
  </body>  
```

``` js
   //傳統的DOM加載  
  window.onload = function () {  
      var box = document.getElementById('box');           
      alert(box.innerHTML);  
  };  
    
```

//PS:如果有圖片,那么圖片加載完畢后,方可執行onload里面的內容  

二、解決方案

   非IE瀏覽器提供了一種加載事件:DOMContentLoaded事件,這個事件可以在完成HTML DOM結構之后就會觸發,不會理會圖像音樂、JS文件、CSS文件或其他資源是否已經下載完畢。

目前支持DOMContentLoaded事件瀏覽器有:IE9+、Firefox、Chrome、Safari 3.1+和Opera 9+都支持。

``` html
  //DOMContentLoaded事件加載  
  if (document.addEventListener) {                //DOM結構加載完畢  
      addEvent(document, 'DOMContentLoaded', function () {  
          var box = document.getElementById('box');  
          alert(box.innerHTML);  
      });  
  }   
  <span style="font-size:14px;color:#333333;"><span style="font-family:宋體;">//PS:如果有圖片,先執行節點操作的內容,然后再緩緩加載圖片,也就是說,當DOM樹結構加載完畢后即可執行了</span></span>  
  <span style="font-size:14px;color:#333333;"><span style="font-family:宋體;"></span></span>  
``` 

   
IE不支持DOMContentLoaded事件,可以采用方式:創建空script標簽,屬性擁有defer,這個屬性就是定義需要加載完畢后執行,然后待onreadystatechange為complete時,表示DOM結構加載完畢了,再執行。

``` html
  //IE瀏覽器加載  
  document.write("<script id=\"ie_onload\" defer=\"defer\" src=\"javascript:void(0)\">  
  <\/script>");  
  var script = document.getElementById("ie_onload");  
  script.onreadystatechange = function () {  
      if (this.readyState=='complete') {  
          var box = document.getElementById('box');  
          alert(box.innerHTML);  
      }  
  };  
``` 

    
   另外,在IE瀏覽器如果網頁上有<iframe>加載另一個網頁,我們發現IE瀏覽器還需要加載完畢iframe所有的內容才可以執行。而非IE瀏覽器的DOMContentLoaded事件則還是DOM加載完畢后就執行了,在這里我們就發現IE的這種方式並不完美,當然,如果頁面沒有iframe的話就夠用了。



  在IE中,任何DOM元素都有一個doScroll 方法,無論它們是否支持滾動條。為了判斷DOM樹是否建成,我們只看看documentElement是否完整就是,因為,它作為最外層的元素,作為 DOM樹的根部而存在,如果documentElement完整的話,就可以調用doScroll方法了。當頁面一加載JS時,我們就執行此方法,當然要 如果documentElement還不完整就會報錯,我們在catch塊中重新調用它,一直到成功執行,成功執行時就可以調用 fn方法了

``` js
  //使用doScroll()來判斷DOM加載完畢  
  var timer = null;  
  timer = setInterval(function () {  
      try {  
          document.documentElement.doScroll('left');  
          var box = document.getElementById('box');  
          alert(box.innerHTML);  
      } catch (ex) {};  
  });  

``` 


由此,我們可以結合一下上面兩種方案,做一個兼容的函數方便調用。

``` js
  function addDomLoaded(fn) {  
      if (document.addEventListener) {            //W3C  
          addEvent(document, 'DOMContentLoaded', function () {  
              fn();  
              removeEvent(document, 'DOMContentLoaded', arguments.callee);  
          });  
      }   
      else {                              //IE  
          var timer = null;  
          timer = setInterval(function () {  
              try {  
                  document.documentElement.doScroll('left');  
                  fn();  
              } catch (ex) {};  
          });  
      }  
  }  
    
  addDomLoaded(function () {  
      var box = document.getElementById('box');  
      alert(box.innerHTML);  
  });  
  //PS:有效,DOM加載完畢后執行了節點操作,並且后面才加載完畢圖片
``` 


三、總結:
雖然以上對於主流瀏覽器和主流瀏覽器的版本已經非常夠用了,但還有幾個小細節我們需要了解一下。Opera8之前不支持,webkit引擎瀏覽器525之前不支持,Firefox2有嚴重bug。
對於非IE,又不支持DOMContentLoaded,可以直接用傳統的window.onload來執行,因為目前來說這種瀏覽器基本滅絕了,也可以document.readyState輪詢,直到完畢。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM