延时加载图片(原创)
访问淘宝的朋友会发现淘宝的产品展示页通常比较长,然后在中间部分有许多张大图(尤其是一些展示衣服的网页),通常有许多用户在打开这个网页后,仅仅是看个价格或简短文字介绍就离开页面了。但整个页面上的大部分图片都已经加载了,或者因为图片未下载完毕导致整个html页迟迟未完成加载,造成用户体验的确实。一些图片很多的网页因为有大量图片动辄达到几mb,由此也造就浪费了极大的带宽。
那有没有办法可以在用户需要看到某张图片的时候再加载图片呢?这样用户如果没有浏览整个网页,图片也不会全部加载,对一些B2C和门户网站来说,积少成多,节省下的流量是非常可观的。使用延时加载技术,可以达到这个目的。
有一个jquery插件叫做Lazy Load Plugin for jQuery(http://www.appelsiini.net/projects/lazyload),在实质上,这个jquery控件并仅仅是
延时显示,并没有达到省带宽的目的。我们可以使用firebug来监控一下,如下图:
我们可以看到,在html页面一加载完毕,所有的图片都已经被加载出来了,在页面向下滚动的过程中,图片仅仅是延时显示出来而已,并没有达到省带宽的目的(有兴趣的朋友可以到http://www.appelsiini.net/projects/lazyload/enabled.html这个地址用firebug测测)。而且这个控件还要预设图片的高和宽。
下边看看使用我的代码达到的效果,同样的页面减少了好几个请求,图片仅仅加载了1张。
在页面上向下滚动滑鼠,可以看到图片被加载了
以下是代码延时加载的代码
var lazyLoad = {
/// <summary>
/// 存储图片路径名的集合
/// </summary>
ArrLoad: null,
/// <summary>
/// img标签中的存放图片路径的自定义属性名称
/// </summary>
AttributeName: "lazyload",
/// <summary>
/// 初始化。自动加载第一张图片,并将所有需要延时加载的图片放到数组中
/// </summary>
Init: function (v) {
if (v != undefined && v != null && typeof (v) == "string") {
this.AttributeName = v;
}
var lazyLoadObject = $("img[" + this.AttributeName + "]");
//检查图片集合数量是否等于0
if (lazyLoadObject.length == 0) {
return null;
}
else {
var src = lazyLoadObject.eq(0).attr(this.AttributeName);
var src1 = lazyLoadObject.eq(0).attr("lazyload");
//自动将第一张图片加载出来
lazyLoadObject.eq(0).attr("src", lazyLoadObject.eq(0).attr(this.AttributeName));
lazyLoadObject.eq(0).removeAttr(this.AttributeName);
//将所有图片路径存于集合之中
this.ArrLoad = new Array();
var _this = this;
lazyLoadObject.each(function () {
_this.ArrLoad.push($(this).attr(_this.AttributeName));
});
this.ArrLoad.shift();
}
},
/// <summary>
/// 当scroll事件被触发时,进行加载图片的操作
/// </summary>
LoadImage: function (scrolltop) {
//获取窗体的高度
var windowHeight = $(window).height();
//存储当前滚动处的img对象
var currentObj = null;
var nextObj = null;
if ($("img[" + this.AttributeName + "]").eq(0).attr(this.AttributeName) == this.ArrLoad[0]) {
if ($("img[" + this.AttributeName + "]").size() > 0) {
currentObj = $("img[" + this.AttributeName + "]").eq(0);
}
}
if (currentObj == null) {
return null;
}
//获取当前图片相对于页面顶部的偏移量
var _scrollTop = currentObj.offset().top - windowHeight + currentObj.height();
//根据scrollTop判断是否显示图片
if (parseInt(scrolltop) >= parseInt(_scrollTop)) {
//判断是否有下一张图片
if (this.ArrLoad[0] != undefined && this.ArrLoad[0] != null) {
//加载下一张图片
if ($("img[" + this.AttributeName + "]").eq(0).attr(this.AttributeName) == this.ArrLoad[0]) {
nextObj = $("img[" + this.AttributeName + "]").eq(0);
}
if (nextObj != null && nextObj.attr(this.AttributeName) != undefined) {
nextObj.attr("src", nextObj.attr(this.AttributeName));
nextObj.removeAttr(this.AttributeName);
}
//将已加载的图片从集合中移除
this.ArrLoad.shift();
currentObj.removeAttr(this.AttributeName);
}
}
},
/// <summary>
/// 启动延时加载
/// <params key="v">img标签中的存放图片路径的自定义属性名称</params>
/// </summary>
Run: function (v) {
this.Init(v);
if (this.ArrLoad == null) {
return false;
}
else {
var _this = this;
//添加scroll事件
$(window).scroll(function () {
_this.LoadImage($(this).scrollTop());
});
}
}
};
调用也很简单,仅需在最后一张需要延时加载的图片后加上如下js代码即可
<script type="text/javascript">
lazyLoad.Run();
</script>
在另一篇文章(http://www.cnblogs.com/windinsky/archive/2010/07/12/1775582.html)中对代码进行了精简和优化,推荐大家使用那一个。