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

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

效果预览

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


















































程序说明

【获取图片】

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

代码

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不存在的:

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程序中,主要是用来显示图片。

先用_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来移除自定义属性。
移除的意义在于,当有多个实例使用同一个元素时,能保证图片加载一次后就不会重复加载,即防止实例间的冲突。

【图片的HTTP请求】

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

首先是加载空字符串的问题,如果给img的src设为空字符串的话,可能会得到意料之外的结果。
例如在 http://xxx/test.htm 里面的 <img src=""> 会发生以下情况:
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。
其中第一个参数是子类的可选属性,第二个参数是子类定义的属性,即不再是可选而是由程序来定义的属性。

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

使用技巧

【设置src】

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

【设置holder】

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

【执行程序】

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

程序源码

代码

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 );
    }
  }
});

完整实例下载

转载请注明出处:http://www.cnblogs.com/cloudgamer/

如有任何建议或疑问,欢迎留言讨论。

如果觉得文章不错的话,欢迎点一下右下角的推荐。

最新作品:ImagesLazyLoad 图片延迟加载效果

ImagesLazyLoad 图片延迟加载效果相关推荐

  1. 基于原生js的图片延迟加载

    当页面图片比较多的时候,我们通常会做一个延迟加载,避免页面打开时一下子的请求数太多,加载过慢影响用户体验. 如果项目用了jquery框架,则可以直接用 jquery.lazyload.可在jquery ...

  2. jquery图片延迟加载 lazy-src

    http://tanglangrong2010.blog.163.com/blog/static/174796716201211282555345/ 目前,主要的购物网站都采用了这种加载方式.今天在一 ...

  3. jQuery图片延迟加载插件jQuery.lazyload

      查看演示   website   立即下载 插件描述:jQuery图片延迟加载插件jQuery.lazyload,使用延迟加载在可提高网页下载速度.在某些情况下,它也能帮助减轻服务器负载. 使用方 ...

  4. JQuery LazyLoad实现图片延迟加载-探究

    对于大量图片的网站,图片延迟加载是提高速度和性能的好方法. 目前图片延迟加载主要分两大块,一是触发加载(根据滚动条位置加载图片):二是自动预加载(加载完首屏后n秒后自动加载其他位置的图片).大体常用的 ...

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

    在页面中图片较多时,一次性加载所有图片会耗去很多时间. 我们可以选择"延迟加载"的方式来加载图片,相对这种页面的加载速度将会有个很大的提升. 图片延迟加载的原理很简单,依据用户正浏 ...

  6. 图片延迟加载对seo有什么影响呢?

    我们在做seo时,图片的应用应该是每一个网站都要做的工作,主要是为了提高网站内容的丰富性,当然也有搜索引擎判断网站质量的考虑,但我们也经常会发现,图片延迟加载速度,只是对不同网站的加载速度影响不同而已 ...

  7. js实现点击图片放大效果,以及懒加载图片

    js实现点击图片放大效果,以及懒加载图片 近期有个后端管理页面小优化,原来的图片是点击才会去后端请求图片展示到前端,用dialog的方式展示,但是不太直观 存在两个问题 1.点击查看后,电子照片会变形 ...

  8. 利用Jquery Lazyload JS插件实现网页图片延迟加载

    Jquery Lazyload是一款网页图片延迟加载JS插件,本文介绍该JS的使用方法. 最新的jquery lazyload可以单独使用(即不依赖jquery),本文介绍的是依赖jquery的使用及 ...

  9. 使用jquery插件实现图片延迟加载技术

    有时我们看到一些大型网站,页面如果有很多图片的时候,当你滚动到相应的行时,当前行的图片才即时加载的,这样子的话页面在打开只加可视区域的图片,而其它隐藏的图片则不加载,一定程序上加快了页面加载的速度,对 ...

最新文章

  1. 施一公:优秀博士如何养成(全文) 清华大学演讲
  2. IBS illustrator for the presentation and visualization of biological sequences 中山大学
  3. 图论算法》关于tarjan算法两三事
  4. Leetcode--96. 不同的二叉搜索树(java)
  5. 轻量级数据sqlite的C++调用示例
  6. 回溯算法 思路清晰,通俗易懂!!!!!!!
  7. 终端仿真程序_SecureCRT for mac(终端SSH工具)
  8. HDFS YARN zookeeper HBASE HIVE HIVE hwi的启动
  9. 车牌定位html5,车牌识别(一)——车牌定位(附详细代码及注释)
  10. 基于Pytorch实现的声音分类
  11. DB2 执行SQL报错: DB2 SQL Error: SQLCODE=-1585, SQLSTATE=54048
  12. 自己实现的水版MPI_Bcast(使用binomial tree,跟mpich2实现思路一样)
  13. 桃词典 Peach Dictionary 简易英语词典app开发 安卓软件开发 Part 7
  14. 可转债网格交易策略回测
  15. [转] TCP/IP原理、基础以及在Linux上的实现
  16. @Autowired和@Resource区别
  17. Android开发——贝塞尔曲线解析
  18. js-三阶贝塞尔曲线计算公式
  19. 病理切片染色技术和生物医学基础知识
  20. 爬取豆瓣电影top250(正则表达式)

热门文章

  1. 信息学奥赛一本通 1015:计算并联电阻的阻值 | OpenJudge NOI 1.3 10
  2. 信息学奥赛一本通(1328:【例7.7】光荣的梦想)
  3. 搜索 —— 启发式搜索
  4. 红黑树结构完整实现与详解
  5. oracle数据表空间与数据文件,oracle 操作表空间和数据文件
  6. 无法将类型int隐式转换为string_Scala implicit 隐式转换安全驾驶指南
  7. C++:遍历指定路径下的文件/图片
  8. linux 关于虚拟内存的几个系统调用
  9. spark-submit的使用
  10. gem install sass 本地配置和淘宝源无效的解决办法