jquery图片延迟加载 前端开发技能必备系列


Posted in Javascript onJune 18, 2012

目前,主要的购物网站都采用了这种加载方式。今天在一个网友的站里发现一个图片延迟加载的插件,很好用,在这里介绍一下。
先介绍一下图片延迟加载原理。我们需要先将图片的真实地址保存在一个自定义的属性中(属性名任你发挥吧,这里我用的是lazy-src),而图片的src属性中用一个占位图片来替代,这个占位图片当然是越小越好,它基本上只干活、不露面。

<img src="images/placeholder.png" lazy-src="images/realimg.jpg" alt="" /> 
<!-- 如果浏览器禁用了js,我们也不能不让网页显示图片撒,所以最好是加上下面一句备用代码 --> 
<noscript><img src="images/realimg.jpg" alt="" /></noscript>

首先。页面开始加载时浏览器会获取所有图片在当前页面中的位置并缓存(获取offset的值时,页面的reflow会被引发),计算出可视区域,当图片的位置出现在可视区域中,利用js动态地将图片标签中的src值替换成图片真实的地址,这时,刚刚出现在可视区域的图片便开始加载。
其次。当用户向下滚动页面时,通过js再次计算是否有图片初次出现可视区域内,如果有,刚对这些图片的src值进行替换,并开始加载真实图片。为了避免重复操作引起的内存泄漏,需要在全部图片加载完后,卸载掉相应的触发事件。
最后。本文是将整个窗口看成是一个大容器,如果愿意,也可以在页面中设置一个小容器,在小容器中也同样可以实现图片的延迟加载。原理虽然简单,但是应用是多样的。
从下面的地址可以看到图片延迟加载的演示,不过尽量使用相应的工具(firebug、Fiddler2)监测图片延迟加载的效果。
图片延迟加载插件的代码如下:
图片延迟加载插件代码 
(function( $ ){ 
$.fn.imglazyload = function( options ){ 
var o = $.extend({ 
attr : 'lazy-src', 
container : window, 
event : 'scroll', 
fadeIn : false, 
threshold : 0, 
vertical : true 
}, options ), 
event = o.event, 
vertical = o.vertical, 
container = $( o.container ), 
threshold = o.threshold, 
// 将jQuery对象转换成DOM数组便于操作 
elems = $.makeArray( $(this) ), 
dataName = 'imglazyload_offset', 
OFFSET = vertical ? 'top' : 'left', 
SCROLL = vertical ? 'scrollTop' : 'scrollLeft', 
winSize = vertical ? container.height() : container.width(), 
scrollCoord = container[ SCROLL ](), 
docSize = winSize + scrollCoord; 
// 延迟加载的触发器 
var trigger = { 
init : function( coord ){ 
return coord >= scrollCoord && 
coord <= ( docSize + threshold ); 
}, 
scroll : function( coord ){ 
var scrollCoord = container[ SCROLL ](); 
return coord >= scrollCoord && 
coord <= ( winSize + scrollCoord + threshold ); 
}, 
resize : function( coord ){ 
var scrollCoord = container[ SCROLL ](), 
winSize = vertical ? 
container.height() : 
container.width(); 
return coord >= scrollCoord && 
coord <= ( winSize + scrollCoord + threshold ); 
} 
}; 
var loader = function( triggerElem, event ){ 
var i = 0, 
isCustom = false, 
isTrigger, coord, elem, $elem, lazySrc; 
// 自定义事件只要触发即可,无需再判断 
if( event ){ 
if( event !== 'scroll' && event !== 'resize' ){ 
isCustom = true; 
} 
} 
else{ 
event = 'init'; 
} 
for( ; i < elems.length; i++ ){ 
isTrigger = false; 
elem = elems[i]; 
$elem = $( elem ); 
lazySrc = $elem.attr( o.attr ); 
if( !lazySrc || elem.src === lazySrc ){ 
continue; 
} 
// 先从缓存获取offset值,缓存中没有才获取计算值, 
// 将计算值缓存,避免重复获取引起的reflow 
coord = $elem.data( dataName ); 
if( coord === undefined ){ 
coord = $elem.offset()[ OFFSET ]; 
$elem.data( dataName, coord ); 
} 
isTrigger = isCustom || trigger[ event ]( coord ); 
if( isTrigger ){ 
// 加载图片 
elem.src = lazySrc; 
if( o.fadeIn ){ 
$elem.hide().fadeIn(); 
} 
// 移除缓存 
$elem.removeData( dataName ); 
// 从DOM数组中移除该DOM 
elems.splice( i--, 1 ); 
} 
} 
// 所有的图片加载完后卸载触发事件 
if( !elems.length ){ 
if( triggerElem ){ 
triggerElem.unbind( event, fire ); 
} 
else{ 
container.unbind( o.event, fire ); 
} 
$( window ).unbind( 'resize', fire ); 
elems = null; 
} 
}; 
var fire = function( e ){ 
loader( $(this), e.type ); 
}; 
// 绑定事件 
container = event === 'scroll' ? container : $( this ); 
container.bind( event, fire ); 
$( window ).bind( 'resize', fire ); 
// 初始化 
loader(); 
return this; 
}; 
})( jQuery );

有关这个的插件API说明如下:
attr string
存放图片真实地址的属性名,与HTML对应,默认是lazy-src。
container dom & selector
默认的容器为window,可自定义容器。
event stirng
触发图片加载的事件类型,默认为window.onscroll事件
fadeIn boolean
是否使用jQuery的fadeIn效果来显示,默认是false。
threshold number
页面滚动到离图片还有指定距离的时候就进行加载,默认是0。
vertical boolean
是否横向滚动,默认为true(纵向)。
loadScript(增强版的功能) boolean
是否无阻塞加载javascript广告图片,默认为false。

注:转载请注明出处。作者:爱莲学堂

Javascript 相关文章推荐
Javascript 通过json自动生成Dom的代码
Apr 01 Javascript
基于jquery的checkbox下拉框插件代码
Jun 25 Javascript
jQuery动态添加删除select项(实现代码)
Sep 03 Javascript
IE浏览器不支持getElementsByClassName的解决方法
Aug 27 Javascript
Bootstrap+jfinal实现省市级联下拉菜单
May 30 Javascript
jQuery Ajax页面局部加载方法汇总
Jun 02 Javascript
AngularJS实用开发技巧(推荐)
Jul 13 Javascript
vue系列之动态路由详解【原创】
Sep 10 Javascript
浅谈jquery中ajax跨域提交的时候会有2次请求的问题
Nov 10 jQuery
安装vue-cli的简易过程
May 22 Javascript
详解vue2.0+axios+mock+axios-mock+adapter实现登陆
Jul 19 Javascript
jQuery实现移动端扭蛋机抽奖
Nov 08 jQuery
jquery不会自动回收xmlHttpRequest对象 导致了内存溢出
Jun 18 #Javascript
Jquery上传插件 uploadify v3.1使用说明
Jun 18 #Javascript
uploadify 3.0 详细使用说明
Jun 18 #Javascript
通过Javascript创建一个选择文件的对话框代码
Jun 16 #Javascript
通过Javascript将数据导出到外部Excel文档的函数代码
Jun 15 #Javascript
精心挑选的15个jQuery下拉菜单制作教程
Jun 15 #Javascript
jQuery操作input type=radio的实现代码
Jun 14 #Javascript
You might like
windows xp下安装pear
2006/12/02 PHP
php mysql数据库操作分页类
2008/06/04 PHP
php调用方法mssql_fetch_row、mssql_fetch_array、mssql_fetch_assoc和mssql_fetch_objcect读取数据的区别
2012/08/08 PHP
深入理解PHP中的empty和isset函数
2016/05/26 PHP
自制PHP框架之路由与控制器
2017/05/07 PHP
Yii2设置默认控制器的两种方法
2017/05/19 PHP
解决jquery .ajax 在IE下卡死问题的解决方法
2009/10/26 Javascript
不要在cookie中使用特殊字符的原因分析
2010/07/13 Javascript
DOM 中的事件处理介绍
2012/01/18 Javascript
使用Plupload实现直接上传附件至七牛云存储
2014/12/26 Javascript
JavaScript判断IE版本型号
2015/07/27 Javascript
js实现表单检测及表单提示的方法
2015/08/14 Javascript
仅一个form表单 js实现注册信息依次填写提交功能
2016/06/12 Javascript
详解angularJs中自定义directive的数据交互
2017/01/13 Javascript
原生JavaScript实现Tooltip浮动提示框特效
2017/03/07 Javascript
vue.js移动端tab组件的封装实践实例
2017/06/30 Javascript
利用jQuery异步上传文件的插件用法详解
2017/07/19 jQuery
JS中移除非数字最多保留一位小数
2018/05/09 Javascript
基于vue写一个全局Message组件的实现
2019/08/15 Javascript
centos6.4下python3.6.1安装教程
2017/07/21 Python
python 把列表转化为字符串的方法
2018/10/23 Python
Python安装及Pycharm安装使用教程图解
2019/09/20 Python
TensorFlow自定义损失函数来预测商品销售量
2020/02/05 Python
关于keras中keras.layers.merge的用法说明
2020/05/23 Python
python与js主要区别点总结
2020/09/13 Python
python爬虫爬取网页数据并解析数据
2020/09/18 Python
CSS实现进度条和订单进度条的示例
2020/11/05 HTML / CSS
HTML5+JS实现俄罗斯方块原理及具体步骤
2013/11/29 HTML / CSS
用html5绘制折线图的实例代码
2016/03/25 HTML / CSS
阿联酋航空官方网站:Emirates
2017/10/17 全球购物
五一服装活动方案
2014/01/11 职场文书
小学生环保演讲稿
2014/04/25 职场文书
大学生毕业求职信
2014/06/12 职场文书
四十年同学聚会致辞
2015/07/28 职场文书
P站美图推荐——变身女主角特辑
2022/03/20 日漫
Python的代理类实现,控制访问和修改属性的权限你都了解吗
2022/03/21 Python