ImagesLazyLoad 图片延迟加载效果

季风吹过的夏天

季风吹过的夏天

2016-02-20 01:04

下面图老师小编跟大家分享ImagesLazyLoad 图片延迟加载效果,一起来学习下过程究竟如何进行吧!喜欢就赶紧收藏起来哦~

之前在做一个图片浏览效果时,要看后面的小图必须等到前面的加载完,而且大图的位置是在大量的小图后面,导致大图要等到小图都加载完才能显示,为了解决这个问题,就想到了Lazyload效果。
现在很多网站都用了类似的效果,如淘宝、Bing等。
这个图片延迟加载效果是在Lazyload的基础上扩展的,主要扩展了获取img元素,获取src和图片加载的部分。

兼容:ie6/7/8, firefox 3.5.5, opera 10.10, safari 4.0.4, chrome 3.0
其中safari和chrome部分功能不支持。


效果预览

图片延迟加载:共有图片张,未载入 张 photo photo photo photo photo

 

程序说明

先定义filter函数作为筛选程序:

photophoto代码 var getSrc = opt.getSrc,
filter = $$F.bind( this._filter, this,
opt["class"],
getSrc ? function(img){ return getSrc(img); }
: function(img){ return img.getAttribute( attribute ) || img.src; },
opt.holder
);


然后用这个filter函数筛选出需要的图片集合:

this._elems = $$A.filter(
opt.images || container.getElementsByTagName("img"), filter
);

如果要自定义图片集合可以在程序可选参数的images属性来设置,否则自动从容器获取img元素作为图片集合。

这里的filter其实是包装了筛选样式cls、获取src的方法getSrc和占位图holder三个参数的_filter筛选程序。
在_filter程序中,会对图片集合进行筛选和整理。
如果自定义了"class"筛选样式,会自动排除样式不对应的图片:

if ( cls && img.className !== cls ) return false;


再用getSrc获取原图地址,即实际要显示的图片地址。
如果有自定义getSrc会优先使用。
没有的话,再通过保存原图地址的_attribute自定义属性从元素获取。
最后才直接从元素的src属性获取。

接着排除src不存在的:

(本文来源于图老师网站,更多请访问http://m.tulaoshi.com/webkaifa/)if ( !src ) return false;


要注意处理原图地址就是元素当前src的情况:

if ( src == img.src ) {
if ( img.complete || $$B.chrome || $$B.safari ) return false;
img.removeAttribute("src");
}

如果complete为true,说明图片已经载入完成了,可以排除;
如果是chrome或safari,不能取消当前加载,所以也排除掉(具体看图片的HTTP请求部分)。
否则,用removeAttribute移除src属性来取消图片当前的加载。

如果设置了holder占位图,就重新设置图片src:

if ( holder ) { img.src = holder; }


最后把原图地址记录到元素的_attribute自定义属性中:

img.setAttribute( this._attribute, src );


逐个图片元素筛选整理后,就得到要加载的图片集合了。

ImagesLazyLoad相比LazyLoad,已经实现了_onLoadData加载程序,不需要再自己定义加载。
在_onLoadData程序中,主要是用来显示图片。

(本文来源于图老师网站,更多请访问http://m.tulaoshi.com/webkaifa/)

先用_hasAttribute方法判断是否有_attribute自定义属性。
在_hasAttribute方法中是这样判断的:

this._hasAttribute = $$B.ie6 || $$B.ie7
? function(img){ return attribute in img; }
: function(img){ return img.hasAttribute( attribute ); };

由于ie6/7跟其他浏览器对attribute和property的理解不同,所以要分开处理,详细参考这里的attribute/property。
为了保证兼容性,程序会优先使用attribute的方式来操作自定义属性。

当img有_attribute自定义属性时,就用getAttribute来获取原图地址,并设置img的src,在用removeAttribute来移除自定义属性。
移除的意义在于,当有多个实例使用同一个元素时,能保证图片加载一次后就不会重复加载,即防止实例间的冲突。

这里说说开发过程中发现的一些关于图片加载的问题。

首先是加载空字符串的问题,如果给img的src设为空字符串的话,可能会得到意料之外的结果。
例如在 http://xxx/test.htm 里面的  会发生以下情况:
ie 会产生相对地址的请求,即:http://xxx/
Safari/Chrome 会产生当前页面地址的请求,即:http://xxx/test.htm
Opera/Firefox 不会产生请求
详细参考Nicholas C. Zakas的Empty image src can destroy your site。
如果不想加载图片,不应该把src设为空值,因为还可能会发出请求,浪费资源。
可以像程序那样,通过removeAttribute来移除就行了。

还有一个问题是在Safari和Chrome,由于webkit内核的bug,正在加载的图片并不能取消加载。
所以程序在取消图片加载的部分,如果是Safari或Chrome会继续加载,不进行延迟。
这个问题最初从lifesinger的datalazyload的说明部分看到的,具体可以自己用Fiddler来测试。

更多相关资料可以参考lifesinger的图片的HTTP请求。

在发布的程序中,这是第一个用了继承的,本人平时也没怎么用到,所以还不成熟,算是试试水吧。
程序用wrapper来做继承,详细参考工具库的说明。
先用wrapper给ImagesLazyLoad包装(继承)LazyLoad:

var ImagesLazyLoad = $$.wrapper(function(options) {
...
}, LazyLoad);


再用extend扩展prototype,添加子类的方法函数:

$$.extend( ImagesLazyLoad.prototype, {
...
});


其中_initialize方法用来设置子类属性,由于覆盖了父类的同名方法,所以要通过LazyLoad.prototype._initialize来调用,还要注意用call来修正this。

还有_setOptions方法用来设置子类的可选属性:

return LazyLoad.prototype._setOptions.call(this, $$.extend({
...
}, $$.extend( options, {
onLoadData: this._onLoadData
})));

子类的_setOptions方法也覆盖了父类的方法,解决方法同_initialize。
其中第一个参数是子类的可选属性,第二个参数是子类定义的属性,即不再是可选而是由程序来定义的属性。

总体来说,这是个简陋的继承,等以后积累了一定经验再来扩展吧。


使用技巧

有几个方法可以设置原图地址:
1,正常设置src:渐进增强,不支持js时也能显示,但chrome和safari有bug,不支持这种方式;
2,把原图地址设置到自定义属性中:所有浏览器都兼容,但在不支持js时图片不能显示;
3,用自定义函数获取:使用在比较复杂的情况,需要手动设置。
具体还是要根据实际情况来选择。

如果使用了holder占位图,程序会自动设置图片元素显示占位图。
推荐使用loading图片来设置,但loading图往往跟原图的尺寸是不同的。
如果img设置了原图宽高,又想保持loading图的尺寸,把它设为背景就可以了。
但这样在ie下,不设置src默认会有一个小图标。
要去掉这个小图标可以设置holder为一个透明图片的链接,或者参考这里的TRANSPARENT做一个透明图片。
实例中也是这样设置的,可以参考一下。

千万不能在window.onload中执行,因为那时图片都已经加载完了。
而应该在容器后面(window的话是文档结尾)或DOMContentLoaded中执行。


程序源码

photophoto代码 var ImagesLazyLoad = $$.wrapper(function(options) {
this._initialize( options );
//如果没有元素就退出
if ( this.isFinish() ) return;
//初始化模式设置
this._initMode();
//进行第一次触发
this.resize(true);
}, LazyLoad);

$$.extend( ImagesLazyLoad.prototype, {
//初始化程序
_initialize: function(options) {
LazyLoad.prototype._initialize.call(this, [], options);
//设置子类属性
var opt = this.options;
this.onLoad = opt.onLoad;
var attribute = this._attribute = opt.attribute;
//设置加载图片集合
var getSrc = opt.getSrc,
filter = $$F.bind( this._filter, this,
opt["class"],
getSrc ? function(img){ return getSrc(img); }
: function(img){ return img.getAttribute( attribute ) || img.src; },
opt.holder
);
this._elems = $$A.filter(
opt.images || this._container.getElementsByTagName("img"), filter
);
//判断属性是否已经加载的方法
this._hasAttribute = $$B.ie6 || $$B.ie7
? function(img){ return attribute in img; }
: function(img){ return img.hasAttribute( attribute ); };
},
//设置默认属性
_setOptions: function(options) {
return LazyLoad.prototype._setOptions.call(this, $$.extend({//默认值
images: undefined,//图片集合
attribute: "_lazysrc",//保存原图地址的自定义属性
holder: "",//占位图
"class": "",//筛选样式
getSrc: undefined,//获取原图地址程序
onLoad: function(){}//加载时执行
}, $$.extend( options, {
onLoadData: this._onLoadData
})));
},
//筛选整理图片对象
_filter: function(cls, getSrc, holder, img) {
if ( cls && img.className !== cls ) return false;//排除样式不对应的
//获取原图地址
var src = getSrc(img);
if ( !src ) return false;//排除src不存在的
if ( src == img.src ) {
//排除已经加载或不能停止加载的
if ( img.complete || $$B.chrome || $$B.safari ) return false;
img.removeAttribute("src");//移除src
}
if ( holder ) { img.src = holder; }
//用自定义属性记录原图地址
img.setAttribute( this._attribute, src );
return true;
},
//显示图片
_onLoadData: function(img) {
var attribute = this._attribute;
if ( this._hasAttribute( img ) ) {
img.src = img.getAttribute( attribute );
img.removeAttribute( attribute );
this.onLoad( img );
}
}
});

 

完整实例下载

展开更多 50%)
分享

猜你喜欢

ImagesLazyLoad 图片延迟加载效果

Web开发
ImagesLazyLoad 图片延迟加载效果

jquery 插件实现图片延迟加载效果代码

Web开发
jquery 插件实现图片延迟加载效果代码

s8lol主宰符文怎么配

英雄联盟 网络游戏
s8lol主宰符文怎么配

java Hibernate延迟加载

编程语言 网络编程
java Hibernate延迟加载

Lazy Load 延迟加载图片的 jQuery 插件

Web开发
Lazy Load 延迟加载图片的 jQuery 插件

lol偷钱流符文搭配推荐

英雄联盟 网络游戏
lol偷钱流符文搭配推荐

jquery.lazyload 实现图片延迟加载jquery插件

Web开发
jquery.lazyload  实现图片延迟加载jquery插件

jquery.lazyload.js实现图片延迟加载插件

Web开发
jquery.lazyload.js实现图片延迟加载插件

lolAD刺客新符文搭配推荐

英雄联盟
lolAD刺客新符文搭配推荐

word如何隐藏去掉回车符

word如何隐藏去掉回车符

JS教程:window.location用法区别

JS教程:window.location用法区别
下拉加载更多内容 ↓