提示:本文参考自 CNBLOGS、鑫空间(我们所使用的插件 ScrollLoading 即由大牛@张鑫旭制作)。
什么是 LazyLoad?
大家的博客或多或少都会有一些图片,当一个页面上图片过多时,网页加载会变慢,而且服务器压力也会增大。所以,一般地,我们使用 jQuery 插件 LazyLoad 来使图片实现延迟加载。但是,iEdon 注意到一些大牛发现 LazyLoad 其实是伪延迟加载,并不能达到真正的效果。
真相:
百度搜索“图片分屏加载”,映入眼帘的就是jquery.lazyload,相信很多人用过,或许现在还在用,今天我就来说说这个插件的严重BUG。
何为图片分屏加载?顾名思义,就是让图片出现在浏览器可视区域内时,才进行加载。好处就是当页面上图片过多时候,不需要一次性加载完,大大提高了友好性,也减轻的服务器的压力。
我们发现,第一屏内的图片,是正常加载了,当滚动到第二张的时候,过了几秒,也渐显出来了,似乎没什么大问题。这时,我们用火狐的firebug再来观看下,当然为了确保测试稳定,我用金山卫士清空了浏览器缓存。
看到了么?说好的分屏加载的效果呢?怎么还是有2个请求。第一屏就一张图片,但实际上已经把两张图片都加载好了。坑爹的还不仅如此,我们继续看,当我把滚动条滑动到第二张图片……
纳尼?第三个请求出现了!!!我一共两张图片,用了jquery.lazyload居然要下载3张,不仅没有减轻服务器压力,反而增加了,这不明摆着坑爹嘛。
之后,我看了下lazyload的源码,其实逻辑上都是OK了,把img的src里的值,存放到自定义的original属性里,当图片滚动到浏览器可视区域内时,再把original里的值赋回到src里,实现分屏加载。
但问题就出在调用上,lazyload的调用方法是写在$().ready(function(){});里,如:
$().ready(function(){ $("#tujie img").lazyload({ effect : "fadeIn", failurelimit : 5 }); });
也就是在页面载入完毕后才调用lazyload,而页面载入完毕后,图片也都下载好了,再去使用 LazyLoad 已经没有必要,反而就会出现上面说的那种情况:一共只有2张图片,却向服务器请求了3次,下载了3张图片,适得其反。
网上有篇修改 jquery.lazyload 的文章,大家可以搜搜,不过我试了下,还是不行,直接不加载了。
关于这问题的解决方法,就是换插件,iEdon 找到另一个分屏加载的插件,叫:jquery.scrollLoading。这个插件真正实现了图片分屏加载。
使用 ScrollLoading:
虽然只有几十行代码,但是为了方便使用,我还是将其插件化了。插件名为 jquery.scrollLoading.js,您可以狠狠地点击这里 下载(右键 – [目标|链接]另存为)。使用 ScrollLoading 还有一个好处,它不仅支持图片延迟,也支持资源延迟(诸如 HTML)。
首先确保你的主题使用了 jQuery,移除 LazyLoad 可能因主题不同而造成差异,这里不做阐述。
在你的主题 header.php 或 footer.php 里面加入:
<script type="text/javascript" [src="将下载的JS上传到你的服务器上后的地址"]></script> <!-- 自行替换中括号内的内容 -->
然后在主题JS或者是直接在HTML中嵌入。
注:此插件的方法名就是scrollLoading,所以,用法就是直接:包装器.scrollLoading();
就可以实现滚动加载效果了,简单的吧。如下:
$(".scrollLoading").scrollLoading();
表示所有class为scrollLoading的元素绑定了滚动加载的方法。
当然,不可能真的就如此简单,我们还需要做点小动作的。元素默认是不加载的,那么真正的加载地址显然要预先在元素上放置的,例如新浪微博默认把头像地址绑在了一个自定义的”dynamic-src”属性上,见下图:
在HTML5中,以data-开头的自定义属性都是合法的,且地址可以是图片,页面等。所以,我设定了绑定地址的自定义属性为”data-original”(在 ScrollLoading 中可以修改自定义属性名称),此属性值设为真实的图片(或页面)地址就可以了。例如下面:
<div class="scrollLoading" data-original="loaded.html">加载中...</div>
会在滚动时加载名为loaded.html的页面,并自动替换里面的内容。
对于常用的图片,还有一点小问题,就是其默认的src图片地址。其src地址不能是真实的图片地址(否则会直接一次性全部加载),也不能是空地址或是坏地址,否则IE浏览器下会出现很惊悚的红叉叉。我的做法是默认链接的是一个1px * 1px的gif透明图片(大小很小),同时可以透出后面加载中gif动画图片,当滚动加载的时候直接把此gif图片替换掉。于是,对于图片,可能就有类似下面的代码:
<img class="scrollLoading" [data-original="http://yourdomain/real.png"] [src="http://yourdomain/lazyloadreplace.gif"] /> <!-- 自行替换中括号内的内容 -->
在 WordPress 中,我们可以修改 functions.php 以及其他调用图片的地方,将属性 src 改为 data-original,并新增一个替代的 src 属性指向延迟加载的 Loading 动画。这里不做阐述,因为这个方法已经烂大街。
附录:ScrollLoading 可选参数
ScrollLoading 是个很简单很小的插件,所以参数也很少,见下表:
参数 | 默认 | 释义 |
---|---|---|
attr | data-original | 获取元素加载地址的属性名 |
container | $(window) | 滚动的容器。默认为$(window),也就是默认的网页滚动。 |
callback | $.noop | 回调。元素动态加载完毕后执行的回调函数。其中回调函数的上下文this 就是当前DOM元素。注意:如果无法获取元素加载地址,则不执行动态加载,但是会触发回调。在某些需求下,您可以缺省url值,仅仅触发回调。 |
一个完整的使用 DEMO:
$(".scrollLoading").scrollLoading({ container: $("#zxxMainCon"), callback: function() { // 我们也可以省略回调,WP用户一般不需要 this.style.border = "3px solid #a0b3d6"; } });
最后,能好好利用 ScrollLoading,就会给你的访客、服务器带来巨大的利处。iEdon 推荐大家使用 ScrollLoading。使用效果可以参考 iEdon Inside。
Leave a Reply