jquery lazyload延遲加載技術的實現原理分析

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

lazyload在什麼場合中應用比較合適?

涉及到圖片,falsh資源,iframe,網頁編輯器(相似FCK)等佔用較大帶寬,且這些模塊暫且不在瀏覽器可視區內,所以可使用lazyload在適當的時候加載該類資源。避免網頁打開時加載過多資源,讓用戶等待過久。程序員

如何實現lazyload?

lazyload的難點在如何在適當的時候加載用戶須要的資源(這裏用戶須要的資源指該資源呈如今瀏覽器可視區域)。所以咱們須要知道幾點信息來肯定目標是否已呈如今客戶區,其中包括:數組

  • 可視區域相對於瀏覽器頂端位置;
  • 待加載資源相對於瀏覽器頂端位置。

在獲得以上兩點數據後,經過以下函數,即可得出某對象是否在瀏覽器可視區域了。
返回瀏覽器的可視區域位置 
瀏覽器

代碼以下:

// 返回瀏覽器的可視區域位置  
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()返回目標模塊區域信息。此時肯定目標模塊是否出如今客戶區其實是肯定如上兩個矩形是否相交。 
app

代碼以下:

// 判斷兩個矩形是否相交,返回一個布爾值  
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事件中編寫一些代碼監控目標區域是否呈如今客戶區。 
jquery插件

代碼以下:

<div ></div>  
<div id="div1" > 
</div> 


代碼以下:

var div1 = document.getElementById("div1");  
window.onscroll = function(){ 
var prec1 = getClient(); 
var prec2 = getSubClient(div1); 
if (intens(prec1, prec2)) { 
alert("true"); 
} 
}; 


咱們只須要在彈出窗口的地方加載咱們須要的資源。 
這裏值得注意的是 : 目標對象呈如今客戶區域時,會隨着滾動而不斷的彈出窗口。所以咱們須要在彈出第一個窗口後取消對該區域的監測,這裏用一個數組來收集須要監測的對象,同時將監測的邏輯抽出來。同時須要注意 onscroll事件和onresize事件都會改變遊覽器可視區域信息,所以在該類事件觸發後須要從新計算,這裏用autocheck()函數實現。 
增長元素 :
編輯器

代碼以下:函數


<div id="div2" >  


代碼以下:

// 比較某個子區域是否呈如今瀏覽器區域  
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("div1"); 
// 子區域二 
var d2 = document.getElementById("div2"); 
// 須要按需加載區域集合 
var arr = [d1, d2]; 
window.onscroll = function(){ 
// 從新計算 
  autocheck(); 
} 
window.onresize = function(){ 
// 從新計算 
autocheck(); }
相關文章
相關標籤/搜索