背景
最近看到很多网站都运用到了一种前端数据延迟加载技术,包括淘宝,新浪网等等,这样做的目的可以使得一些未显示的图片随 着滚动条的滚动进行延迟显示。
好处显而易见,可以减少前端对于图片的Http请求,减轻对于服务器的压力,对于长篇并且大批量的图片的网页很有帮助。
详细分析
1. 今天就来介绍如何设计这样的一种jQuery插件。
jQuery官方也开放一个Lazyload插件,但是用了一下,发现它 有些问题,在网页加载的时候(具体地址可以参考这个Demo:http://www.appelsiini.net/projects/lazyloa d/enabled_container.html),利用HttpWatch可以发现,六张图片其实都有在下载,只是在下载过程中,他会将src路径转换 为orginal路径,当转换为orginal路径时,http请求就会被终止(Aborted),如果拉动滚动条,它会把original路径再转换为src的 路径。同时可以在HttpWatch中观察到它获取得到一个206的HttpCode,206协议是Partial Content,也就是服务端只接收到了部分Http请求。因此,在图片尺寸比较大的情况下,图片加载较慢,因此请求会被拦截,并且保留客户端数据,在下次Img标签加载Load方法的时候,可以继续请求图片数据。HttpWatch查看效果如下:
图上有3个图片的Http请求被终止。
2. 如果我想让它在网页加载的时候,只要没显示的图片,就不要让它去调用请求,那么该如何实现呢?那么开始以下我的设计。
首先,我们考虑到一个Img标签如果具有src属性,并且已经在 Html加载出来的时候,会自动去请求服务端,甚至<img src=” ” />都会去请求服务端。所以,在你加载具有src路径的图片之前,必须让它不被加载,我这里使用到的一个技巧,将包含Img 标签的DOM元素全仍进一个Textarea文本框中,这样就不会去请求路径。
jQuery插件代码:
$.fn.wraplazyload = function (value) {
this .html( ' <textarea class="text-lazyload"> ' + value + ' </textarea> ' );
};
其中将text-lazyload的display设置为none,让它不显示。
接着,我需要开始“解放”图片了
jQuery插件代码:
$( this ).after(content);
这里的this指的是刚才包装的textarea,这里首先把Html内容 的包含“src=”的文本替换为“dynamic=” (注:这里简单进行 这样的替换,如果一般性的考虑的话),
然后创建一个jQuery对象,在textarea后面追加这样的一个DOM 节点。利用dynamic的替代属性,就防止了图片的加载。
3. 该jQuery插件不尽支持对于Img图片的延迟加载,对于任何 一个DOM节点都可以进行延迟加载。
jQuery插件代码:
element为一系列DOM元素或者Img标签,注意这里要使用 visibility:hidden,这样才能保持DOM元素或者Img标签的高度,display:none,会将元素的高度置0.
4. 然后,开始编写滚动条触发事件代码:
jQuery插件代码:
![](https://i-blog.csdnimg.cn/blog_migrate/81178cc93a2a3bb5048d90d76e7ec935.gif)
var pixel = 0 ;
if (settings.position == ' vertical ' ) {
pixel = $(settings.container).height() + $(settings.container).scrollTop();
}
else if (settings.position == ' horizontal ' ) {
pixel = $(settings.container).width() + $(settings.container).scrollLeft();
}
element.each( function () {
if ($( this ).css( ' visibility ' ) != ' visible ' &&
(settings.position == ' vertical ' && pixel >= $( this ).offset().top
|| settings.position == ' horizontal ' && pixel >= $( this ).offset().left)) {
$( this ).css( ' visibility ' , ' visible ' );
if (settings.effect == ' fadeIn ' ) {
$( this ).hide();
$( this )[settings.effect](settings.effectTime);
}
if (settings.loadType == ' item ' )
$( this ).html($( this ).html().replace( / dynamic= / gi, ' src= ' ));
else if (settings.loadType == ' image ' )
$( this ).attr( ' src ' , $( this ).attr( ' dynamic ' )).removeAttr( ' dynamic ' );
}
});
});
当滚动条将图片或者DOM节点给展示出来的时候,会调用$(this).css('visibility', 'visible');
并且如果是加载图片,将调用$(this).attr('src', $(this).attr('dynamic')).removeAttr('dynamic');
如果是加载Dom节点,将调用$(this).html($(this).html ().replace(/dynamic=/gi, 'src='));
思路是将dynamic转换为src,得以进行Http请求。
5. 最后看代码如何应用该插件:
前端JS代码:
![](https://i-blog.csdnimg.cn/blog_migrate/81178cc93a2a3bb5048d90d76e7ec935.gif)
html += ' <div class="item-lazyload"><img src="http://img9.zol.com.cn/desk_pic/big_152/151653.jpg" width="600" height="500" /><br/><img src="http://img9.zol.com.cn/desk_pic/big_413/412107.jpg" width="600" height="500" /></div> ' ;
html += ' <div class="item-lazyload"><img src="http://img9.zol.com.cn/desk_pic/big_152/151656.jpg" width="600" height="500" /></div> ' ;
html += ' <div class="item-lazyload"><img src="http://img9.zol.com.cn/desk_pic/big_413/412108.jpg" width="600" height="500" /></div> ' ;
html += ' <div class="item-lazyload"><img src="http://img9.zol.com.cn/desk_pic/big_419/418139.jpg" width="600" height="500" /></div> ' ;
html += ' <div class="item-lazyload"><img src="http://img9.zol.com.cn/desk_pic/big_152/151647.jpg" width="600" height="500" /></div> ' ;
$( ' #container2 ' ).wraplazyload(html);
$( ' #container2 ' ).datalazyload({ loadType: ' image ' , effect: ' fadeIn ' /* , position: 'horizontal' */ });
Html代码:
</ div >
首先对于container2节点进行包装,然后调用datalazyload方 法,这里loadType加载类型为加载图片“image”,也可以设置为 加载DOM节点“item”,effect为加载效果,position可以设置为 水平加载还是垂直加载,Options参数完整为:
jQuery插件代码:
![](https://i-blog.csdnimg.cn/blog_migrate/81178cc93a2a3bb5048d90d76e7ec935.gif)
dataContainer: ' .text-lazyload ' ,
dataItem: ' .item-lazyload ' ,
loadType: ' item ' , // 可以为item(条目加载),img(图片加载)
container: window, // 滚动的容器
event: ' scroll ' ,
effect: ' normal ' , // 效果类型
effectTime: 1000 , // 效果持续时间
position: ' vertical ' // 可以为vertical(垂直加载),horizontal(水平加载)
};
这些参数都是可设置的,这里不在过多介绍,具体可以查看源代码。
6. 最后,插件只有在滚动条拉到DOM节点或者图片的可视区域的时候,才进行加载,达到了数据延迟加载的效果。该插件已经成功应用到项目中去了.
数据延迟加载JQuery插件的演示地址:http://aspspider.info/sunleepy/lazyload.html