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代码
Aug 13 Javascript
在一个浏览器里呈现所有浏览器测试结果的前端测试工具的思路
Mar 02 Javascript
JS获取节点的兄弟,父级,子级元素的方法
Jan 09 Javascript
JS在IE下缺少标识符的错误
Jul 23 Javascript
使用JQ来编写最基本的淡入淡出效果附演示动画
Oct 31 Javascript
Javascript动画的实现原理浅析
Mar 02 Javascript
JavaScript使用Math.Min返回两个数中较小数的方法
Apr 06 Javascript
jQuery中$.each()函数的用法引申实例
May 12 Javascript
AngularJS入门教程之静态模板详解
Aug 18 Javascript
解决vue2.0 element-ui中el-upload的before-upload方法返回false时submit()不生效问题
Aug 24 Javascript
vue-cli2 构建速度优化的实现方法
Jan 08 Javascript
javascript贪吃蛇游戏设计与实现
Sep 17 Javascript
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
用PHP和ACCESS写聊天室(四)
2006/10/09 PHP
粗略计算在线时间,bug:ip相同
2006/12/09 PHP
组合算法的PHP解答方法
2012/02/04 PHP
PHP 代码规范小结
2012/03/08 PHP
PHP数组及条件,循环语句学习
2012/11/11 PHP
php获取域名的google收录示例
2014/03/24 PHP
php相对当前文件include其它文件的方法
2015/03/13 PHP
CI框架集成Smarty的方法分析
2016/05/17 PHP
PHP命名空间与自动加载类详解
2018/09/04 PHP
php反射学习之依赖注入示例
2019/06/14 PHP
jquery检测input checked 控件是否被选中的方法
2014/03/26 Javascript
javascript单例模式的简单实现方法
2015/07/25 Javascript
11种ASP连接数据库的方法
2015/09/18 Javascript
JavaScript中循环遍历Array与Map的方法小结
2016/03/12 Javascript
js删除Array数组中指定元素的两种方法
2016/08/03 Javascript
Angular实现的内置过滤器orderBy排序与模糊查询功能示例
2017/12/29 Javascript
vue项目中api接口管理总结
2018/04/20 Javascript
vue.js使用3DES加密的方法示例
2018/05/18 Javascript
微信小程序学习笔记之表单提交与PHP后台数据交互处理图文详解
2019/03/28 Javascript
JS实现点餐自动选择框(案例分析)
2019/12/10 Javascript
微信小程序实现自定义动画弹框/提示框的方法实例
2020/11/06 Javascript
[00:14]护身甲盾
2019/03/06 DOTA
Python使用minidom读写xml的方法
2015/06/03 Python
Python中threading模块join函数用法实例分析
2015/06/04 Python
Scrapy基于selenium结合爬取淘宝的实例讲解
2018/06/13 Python
python将txt文档每行内容循环插入数据库的方法
2018/12/28 Python
Django  ORM 练习题及答案
2019/07/19 Python
python如何快速生成时间戳
2020/07/21 Python
用python-webdriver实现自动填表的示例代码
2021/01/13 Python
加拿大在线隐形眼镜专家:PerfectLens.ca
2016/11/19 全球购物
lululemon美国官网:瑜伽服+跑步装备
2018/11/16 全球购物
The North Face北面德国官网:美国著名户外品牌
2018/12/12 全球购物
《在山的那边》教学反思
2014/02/23 职场文书
毕业设计指导教师评语
2014/12/30 职场文书
python3 实现mysql数据库连接池的示例代码
2021/04/17 Python
关于EntityWrapper的in用法
2022/03/22 Java/Android