天猫首页迷思之-jquery实现整个div的懒加载(1)

时间:2024-03-01 18:34:01

懒加载是众所周知的减少网页负载,提高性能的方法,不少大型用图片用的多的网站都用到了。

于是我网上一搜,得到一插件: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

建议在虚拟服务器上启动。

本文仅仅是提供了一个方法用于懒加载,并没有规范的做一个插件。插件如何制作见另一篇文章。