懶加載是眾所周知的減少網頁負載,提高性能的方法,不少大型用圖片用的多的網站都用到了。
於是我網上一搜,得到一插件:jquery.lazyload 網址:http://www.appelsiini.net/projects/lazyload
然而看了簡單的demo之后,仍然只會寫這種按照獨立的控件來懶加載的代碼:
$("img main").lazyload({placeholder:"images/cat_change_cloth.gif"});
既然要做一個肯鑽研的人 ,當然不能止步於此。
簡單觀察以下天貓的首頁。
1.主幻燈片div的第一次張幻燈片的加載,是長這樣的。未加載完成之前,用戶沒法切換其他菜單欄。
2.第一張幻燈片加載完成后,是長這樣的
你沒看錯,不是每張圖片一個懶加載請求,而是多個圖片,一個父div有一個懶加載請求。
那么難點來了。
1. 怎么把加載完成的替代圖片放到中間。
2.怎么把懶加載請求轉移到多個圖片上。
首先,別着急用框架,了解以下jquery.lazyload的實現原理
框架,只針對能設置src的img或者background的div。然而我需要的是能夠懶加載整個div中的元素,包括img和其他元素。
以為自己是沒看懂,找了一天資料也沒找到直接用jquery.lazyload的方法。
好吧,關鍵時刻,特殊需求,還是自己來寫吧。
基本思路:懶加載是通過監聽網頁滾輪,在指定的時刻加載容器中的圖片。那么,加載圖片之前要有一個假的容器像用戶展示正在加載,加載完成之后將innerhtml填充成真正要展示的。
1.給懶加載的div設置默認背景圖片(添加一個class專門展示背景圖片bg-loading),用作placeholder
2.第一次監聽到滾輪到了懶加載div所在的位置,(等到div中圖片全部加載完畢后),去掉bg-loading類,填充innerhtml。
3.此后的每次監聽到滾輪滾到指定位置,都不做任何處理 or 最好是不監聽了。
好,詳細到jquery中的每個操作:
源代碼:
1 <!DOCTYPE html> 2 <html> 3 <header> 4 <meta http-equiv="Content-type" content="text/html;charset=utf-8"> 5 <title>jquery ajax</title> 6 <style type="text/css"> 7 .loading{ 8 background:url(https://img.alicdn.com/tps/i1/TB1Q4fJFVXXXXXiXFXXJgUmHVXX-184-38.gif) no-repeat scroll 50% 50%; 9 } 10 </style> 11 <script src="jquery.min.js"></script> 12 <script type="text/javascript"> 13 $(document).ready(function(){ 14 lazyload_cc("loading",400);//body超出窗口400px之后再啟用 15 16 }); 17 function lazyload_cc(className,beginHeight){ 18 //功能:當div完整出現在屏幕時,加載。 19 //參數className,需要進行懶加載的元素的類名,要取一樣的名字 20 //參數beginHeight,滾動條滾到哪里,開始監聽 21 //必須有inited熟悉你給,request-url屬性,loading的圖片自己准備。可以卸載.loading中。 22 if(!className) { 23 console.error("lazyload_cc方法中缺少className參數"); 24 return; 25 } 26 if(!beginHeight) beginHeight=0; 27 lazyDivList=$("."+className); 28 $(window).scroll(function(){ 29 srcTop=$(window).scrollTop(); 30 if(srcTop>=beginHeight){ 31 lazyDivList.trigger("lazyme",$(window).scrollTop()); 32 } 33 }); 34 lazyDivList.bind("lazyme",function(e,scrTop){ 35 var offset=$(this).offset().top; 36 var interval=$(window).height()-$(this).height();//當前頁面可視高度 37 var sumB=offset; 38 var sumS=offset-interval; 39 var url=$(this).attr("request-url"); 40 41 if(scrTop>=sumS && scrTop<=sumB){ 42 $(this).load(url,function(responseTxt,statusTxt,xhr){ 43 if (statusTxt=="success") { 44 $(this).removeClass(className); 45 $(this).unbind("lazyme"); 46 }; 47 }); 48 } 49 }); 50 } 51 </script> 52 53 </header> 54 <body style="height:3000px;"> 55 <div class="loading" style="border:1px solid black;position:absolute;top:800px;left:500px;width:300px;height:400px;" id="lazyu" request-url="requestU.html">abc</div> 56 <div class="loading" style="border:1px solid black;position:absolute;top:1400px;left:500px;width:300px;height:400px;" id="lazyu2" request-url="requestU2.html">abc2</div> 57 </body> 58 <footer> 59 </footer> 60 </html>
完成插件后,以后要實現類似的效果可以直接使用 lazyload_cc(懶加載類名),默認的beginHeight為0;
效果:
div還沒到頁面中間時,顯示正在加載的背景圖:
div在頁面中間了,顯示要展示的詳細內容:背景圖和原本div.innerhtml都消失了。
源碼git地址:https://github.com/HappyBangs/bang_plugins/tree/master/plugin_TmallLazyLoad
建議在虛擬服務器上啟動。
本文僅僅是提供了一個方法用於懶加載,並沒有規范的做一個插件。插件如何制作見另一篇文章。