Alex的博客

本博客的文章均为原创,是本人从事行业多年来所遇见一些小问题的解决心得,希望可以帮助到大家!



jquery.scrollLoading实现图片滚动加载

一、关于滚动显屏加载

常常会有这样子的页面,内容很丰富,页面很长,图片较多。比如说淘宝商城页面。页面图片数量多,而且比较大时。要是页面载入就一次性加载完毕,需要用户等半天。所以针对这种情况,目前很流行的做法就是滚动动态加载,显示屏幕之外的图片默认是不加载的,随着页面的滚动,这个要显示图片的区域进入了浏览器可是窗口范围,则触发图片的加载显示。这种做法的好处是,一是页面加载速度快(浏览器转啊转的圈圈或是进度条很快就玩完了),二是节约了流量,因为不可能每个用户浏览页面时从头滚到尾的。貌似我上面提到的几个站点就是采用的这种做法,例如,我以迅雷不及掩耳的速度从淘宝商城首页截下来的已触发滚动加载但是未加载完毕的图片:

这是提高前端性能,优化页面加载速度很实用的做法。看上去这种技巧有些技术门槛,其实很简单的。我们需要一个滚动事件,然后判断元素是否在浏览器窗口,然后,显示图片(或是其他元素)就可以啦。我在jQuery库下写了个实现此效果的插件,下面就将简单展示讲解此插件的使用以及滚动动态加载的实现。

二、jQuery滚动加载插件scrollLoading

虽然只有几十行代码,但是为了方便使用,我还是将其插件化了。插件名为jquery.scrollLoading.js,您可以狠狠地点击这里下载(右键 – [目标|链接]另存为),或是点击这里下载mini压缩版的。您可以狠狠地点击这里:jQuery滚动加载图片等demo,如果您的网速是在贫困线上挣扎,可以慢慢拖动滚动条,就可以很清楚的看到滚动加载的效果了;如果您的网速让你引以为豪,哥,你需要很快的拖动滚动条才能瞥见效果。效果类似下面:

demo页面中似乎有段破坏和谐的HTML片段,那是动态加载HTML后的效果,也就是说,此scrollLoading不仅可以用来滚动加载图片,Ajax load页面什么的也是可以的。

三、scrollLoading使用

不管怎样,首先调用jQuery库文件,还有jquery.scrollLoading.js,您可以直接在页面的某处添上如下的代码:

  1. <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.min.js"></script>
  2. <script type="text/javascript" src="http://www.zhangxinxu.com/study/js/mini/jquery.scrollLoading-min.js"></script>

此插件的方法名就是scrollLoading,所以,直接:包装器.scrollLoading();就可以实现滚动加载效果了,简单的吧。如下:

  1. $(".scrollLoading").scrollLoading();

表示所有class为scrollLoading的元素绑定了滚动加载的方法。当然,不可能真的就如此简单,我们还需要做点小动作的。元素默认是不加载的,那么真正的加载地址显然要预先在元素上放置的,例如新浪微博默认把头像地址绑在了一个自定义的”dynamic-src”属性上,见下图:

HTML5中,以data-开头的自定义属性都是合法的,且地址可以是图片,页面等。所以,我设定了绑定地址的自定义属性为”data-url”,此属性值设为真实的图片(或页面)地址就可以了。例如下面:

  1. <div class="scrollLoading" data-url="loaded.html">加载中...</div>

会在滚动时加载名为loaded.html的页面,并自动替换里面的内容。对于常用的图片,还有一点小问题,就是其默认的src图片地址。其src地址不能是真实的图片地址(否则会直接一次性全部加载),也不能是空地址或是坏地址,否则IE浏览器下会出现很惊悚的红叉叉。我的做法是默认链接的是一个1px * 1px的gif透明图片(大小很小),同时可以透出后面加载中gif动画图片,当滚动加载的时候直接把此gif图片替换掉。于是,对于图片,可能就有类似下面的代码:

  1. <img class="scrollLoading" data-url="http://image.zhangxinxu.com/image/study/head/s180/1.jpeg" src="http://www.zhangxinxu.com/study/image/pixel.gif" width="180" height="180" style="background:url(http://www.zhangxinxu.com/study/image/loading.gif) no-repeat center;" />

四、scrollLoading可选参数

scrollLoading是个很简单很小的插件(无注释YUI compressor min版仅508B),所以参数也很少,就一个,见下表:

参数 默认 释义
attr data-url 获取元素加载地址的属性名

就这些了。此插件只适用于页面默认滚动条的动态加载。对于内部div之类的滚动加载不支持。


  1. /*! 
  2.  * jquery.scrollLoading.js 
  3.  * by zhangxinxu  http://www.zhangxinxu.com 
  4.  * 2010-11-19 v1.0 
  5.  * 2012-01-13 v1.1 偏移值计算修改 position → offset 
  6.  * 2012-09-25 v1.2 增加滚动容器参数, 回调参数 
  7. */  
  8. (function($) {  
  9.     $.fn.scrollLoading = function(options) {  
  10.         var defaults = {  
  11.             attr: "data-url",  
  12.             container: $(window),  
  13.             callback: $.noop  
  14.         };  
  15.         var params = $.extend({}, defaults, options || {});  
  16.         params.cache = [];  
  17.         $(this).each(function() {  
  18.             var node = this.nodeName.toLowerCase(), url = $(this).attr(params["attr"]);  
  19.             //重组  
  20.             var data = {  
  21.                 obj: $(this),  
  22.                 tag: node,  
  23.                 url: url  
  24.             };  
  25.             params.cache.push(data);  
  26.         });  
  27.           
  28.         var callback = function(call) {  
  29.             if ($.isFunction(params.callback)) {  
  30.                 params.callback.call(call.get(0));  
  31.             }  
  32.         };  
  33.         //动态显示数据  
  34.         var loading = function() {  
  35.               
  36.             var contHeight = params.container.height();  
  37.             if ($(window).get(0) === window) {  
  38.                 contop = $(window).scrollTop();  
  39.             } else {  
  40.                 contop = params.container.offset().top;  
  41.             }         
  42.               
  43.             $.each(params.cache, function(i, data) {  
  44.                 var o = data.obj, tag = data.tag, url = data.url, post, posb;  
  45.   
  46.                 if (o) {  
  47.                     post = o.offset().top - contop, post + o.height();  
  48.       
  49.                     if ((post >= 0 && post < contHeight) || (posb > 0 && posb <= contHeight)) {  
  50.                         if (url) {  
  51.                             //在浏览器窗口内  
  52.                             if (tag === "img") {  
  53.                                 //图片,改变src  
  54.                                 callback(o.attr("src", url));         
  55.                             } else {  
  56.                                 o.load(url, {}, function() {  
  57.                                     callback(o);  
  58.                                 });  
  59.                             }         
  60.                         } else {  
  61.                             // 无地址,直接触发回调  
  62.                             callback(o);  
  63.                         }  
  64.                         data.obj = null;      
  65.                     }  
  66.                 }  
  67.             });   
  68.         };  
  69.           
  70.         //事件触发  
  71.         //加载完毕即执行  
  72.         loading();  
  73.         //滚动执行  
  74.         params.container.bind("scroll", loading);  
  75.     };  
  76. })(jQuery);  

然后再你页面引用

[javascript] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. <script type="text/javascript" src="<span style="background-color: rgb(255, 255, 102);">jquery.</span>js"></script>  
  2.   
  3. <script type="text/javascript" src="<span style="background-color: rgb(255, 255, 102);">jquery.</span>scrollLoading<span style="color: white; background-color: rgb(0, 170, 0);">.js</span>"></script>  

在加载图片的地方可以这样

[html] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. <img data-url="http://xxx.com/898.jpg.167_167.jpg"  class="lm" align="absmiddle"  width="167" height="167"/>  
然后再加一段js就可以了
[javascript] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. $(function () {  
  2.     $(".lm").scrollLoading();  
  3. });  

这样就搞定 屏幕中出现这个图片的时候,才会进行加载,是不是很方便,

同事你也可以一次返回一个列表 ,比如你想一行几个图片的在屏幕的时候 ,这样你可以ajax放回一个list

[html] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. <div class="searchdiv" data-url="http://xxx.com/xx/imgList.action">  
  2.                     <img src="http://xxxx.com/ui-anim_basic_16x16.gif"  
  3.                         alt="" /></div>  
  4. js:  
  5.    $(function () {  
  6.                         $(".searchdiv").scrollLoading();  
  7.                     });  
上面代码解释:

页面加载完成前DIV显示loading图标,当该DIV的一部分在浏览器的可视范围内时,开始使用ajax加载data-url属性对应的HTML内容,正确返回后填充到该DIV里
赶快试试吧 很简单的。

现在淘宝或者京东这样的电子商务网站 ,都是这样类似实现的。





简单案例


<!DOCTYPE html>
<html>
<head>
  <title></title>
</head>
<body>
  <img class="scrollLoading"  alt="环球美联" style="width:100%;" src="http:/xx.com/img.gif" data-url="/1464328359_2.jpg" />
<script type="text/javascript" src="https://code.jquery.com/jquery-3.2.0.min.js"></script>
<script type="text/javascript">
$(".scrollLoading").scrollLoading();
</script>
</body>

src为默认加载的1像素图片地址

data-url为真是图片地址

浏览444  评论0  Alex于 2017-3-29 13:39
发言