JS懶加載技術lazyload


1.前言
   懶加載技術(簡稱lazyload)並不是新技術, 它是js程序員對網頁性能優化的一種方案.lazyload的核心是按需加載.在大型網站中都有lazyload的身影,例如谷歌的圖片搜索頁,迅雷首 頁,淘寶網,QQ空間等.因此掌握lazyload技術是個不錯的選擇,可惜jquery插件lazy load官網稱不支持新版瀏覽器。


2.lazyload在什么場合中應用比較合適?
   涉及到圖片,falsh資源 , iframe, 網頁編輯器(類似FCK)等占用較大帶寬,且這些模塊暫且不在瀏覽器可視區內,因此可以使用lazyload在適當的時候加載該類資源.避免網頁打開時加載過多資源,讓用戶等待太久.


3.如何實現lazyload?
   lazyload的難點在如何在適當的時候加載用戶需要的資源(這里用戶需要的資源指該資源呈現在瀏覽器可視區域)。因此我們需要知道幾點信息來確定目標是否已呈現在客戶區,其中包括:
     1.可視區域相對於瀏覽器頂端位置
     2.待加載資源相對於瀏覽器頂端位置.

   在得到以上兩點數據后,通過如下函數,便可得出某對象是否在瀏覽器可視區域了.
    

//返回瀏覽器的可視區域位置
    function getClient(){
       var l,t,w,h;
       l  =  document.documentElement.scrollLeft || document.body.scrollLeft;
       t  =  document.documentElement.scrollTop || document.body.scrollTop;
       w =   document.documentElement.clientWidth;
       h =   document.documentElement.clientHeight;
       return {'left':l,'top':t,'width':w,'height':h} ;
    }

    //返回待加載資源位置
    function getSubClient(p){
       var l = 0,t = 0,w,h;
       w = p.offsetWidth ;
       h = p.offsetHeight;

       while(p.offsetParent){
        l += p.offsetLeft ;
        t += p.offsetTop ;
        p = p.offsetParent;
     }

     return {'left':l,'top':t,'width':w,'height':h } ;
    }

 

    其中 函數 getClient()返回瀏覽器客戶區區域信息,getSubClient()返回目標模塊區域信息。此時確定目標模塊是否出現在客戶區實際上是確定如上兩個矩形是否相交.

    //判斷兩個矩形是否相交,返回一個布爾值
    function intens(rec1,rec2){
       var lc1,lc2,tc1,tc2,w1,h1;
       lc1 = rec1.left + rec1.width / 2;
       lc2 = rec2.left + rec2.width / 2;
       tc1 = rec1.top + rec1.height / 2 ;
       tc2 = rec2.top + rec2.height / 2 ;
       w1 = (rec1.width + rec2.width) / 2 ;
       h1 = (rec1.height + rec2.height) / 2;
       return Math.abs(lc1 - lc2) < w1 && Math.abs(tc1 - tc2) < h1 ;
    }

 

    現在基本上可以實現延時加載了,接下來,我們在 window.onscroll 事件中編寫一些代碼監控目標區域是否呈現在客戶區.
     

   <div style = "width:100px; height:3000px"></div>
   <div id  = "d1" style = "width:50px; height:50px; background:red;position:absolute; top:1000px">
   </div>
    var d1 = document.getElementById("d1");
    window.onscroll = function(){
       var prec1 = getClient(); 
       var prec2 =  getSubClient(d1);
        if(intens(prec1,prec2)){
          alert("true")
        }
    }

 

   我們只需要在彈出窗口的地方加載我們需要的資源.
   這里值得注意的是: 目標對象呈現在客戶區域時,會隨着滾動而不斷的彈出窗口.因此我們需要在彈出第一個窗口后取消對該區域的監測,這里用一個數組來收集需要監測的對象,同時 將監測的邏輯抽出來。同時需要注意 onscroll事件和onresize事件都會改變游覽器可視區域信息,因此在該類事件觸發后需要重新計算,這里用autocheck()函數實現. (迅雷首頁的lazyload沒有在onresize事件中重新計算目標對象是否在瀏覽器可視區域,因此如果先將瀏覽器窗口縮小到一定尺寸后滾動到需要加 載圖片的區域后點擊最大化,圖片加載不出來,呵呵,以后需要注意了).

增加元素:

    <div id  = "d2" style = "width:50px; height:50px; background:blue;position:absolute; top:2500px">
   //比較某個子區域是否呈現在瀏覽器區域   function jiance(arr,prec1,callback){    var prec2;    for(var i = arr.length - 1 ; i >= 0 ;i--){      if(arr[i]){      prec2 = getSubClient(arr[i]);      if(intens(prec1,prec2)){       callback(arr[i]);        //加載資源后,刪除監測         delete arr[i];       }     }    }   }   //檢測目標對象是否出現在客戶區   function autocheck(){      var prec1 = getClient();     jiance(arr,prec1,function(obj){       //加載資源...      alert(obj.innerHTML)     })   }   //子區域一    var d1 = document.getElementById("d1");    //子區域二   var d2 = document.getElementById("d2");    //需要按需加載區域集合   var arr = [d1,d2];    window.onscroll = function(){      //重新計算      autocheck();   }   window.onresize = function(){      //重新計算      autocheck();   }



   現在我們只需要在彈窗的地方加載我們需要的資源了.源碼就不貼出來了.如果需要的朋友,或着存在疑問的地方,可以聯系我.


免責聲明!

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



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