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学习笔记(一) 在html中使用javascript
Jun 18 Javascript
jquery的ajax跨域请求原理和示例
May 08 Javascript
javascript弹性运动效果简单实现方法
Jan 08 Javascript
使用jquery获取url及url参数的简单实例
Jun 14 Javascript
漂亮! js实现颜色渐变效果
Aug 12 Javascript
通过网页查看JS源码中汉字显示乱码的解决方法
Oct 26 Javascript
vue2.0获取自定义属性的值
Mar 28 Javascript
十个免费的web前端开发工具详细整理
Sep 18 Javascript
Bootstrap table中toolbar新增条件查询及refresh参数使用方法
May 18 Javascript
详解extract-text-webpack-plugin 的使用及安装
Jun 12 Javascript
微信小程序整个页面的自动适应布局的实现
Jul 12 Javascript
jquery轮播图插件使用方法详解
Jul 31 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
ThinkPHP实例化模型的四种方法概述
2014/08/22 PHP
Symfony2中被遗弃的getRequest()方法分析
2016/03/17 PHP
PHP使用curl_multi_select解决curl_multi网页假死问题的方法
2018/08/15 PHP
JavaScript效率调优经验
2009/06/04 Javascript
javascript new后的constructor属性
2010/08/05 Javascript
推荐10 个很棒的 jQuery 特效代码
2015/10/04 Javascript
实例讲解js验证表单项是否为空的方法
2016/01/09 Javascript
jQuery ajax提交Form表单实例(附demo源码)
2016/04/06 Javascript
AngularJS基础 ng-cloak 指令简单示例
2016/08/01 Javascript
es7学习教程之Decorators(修饰器)详解
2017/07/21 Javascript
Bootstrap 3多级下拉菜单实例
2017/11/23 Javascript
[原创]jquery判断元素内容是否为空的方法
2018/05/04 jQuery
angularjs手动识别字符串中的换行符方法
2018/10/02 Javascript
在JS循环中使用async/await的方法
2018/10/12 Javascript
React-redux实现小案例(todolist)的过程
2019/09/29 Javascript
浅析微信小程序modal弹窗关闭默认会执行cancel问题
2019/10/14 Javascript
vue中上传视频或图片或图片和文字一起到后端的解决方法
2019/12/01 Javascript
vue配置多代理服务接口地址操作
2020/09/08 Javascript
antd design table更改某行数据的样式操作
2020/10/31 Javascript
[49:54]Ti4 循环赛第三日 LGD vs Titan
2014/07/12 DOTA
Python批量按比例缩小图片脚本分享
2015/05/21 Python
TensorFlow入门使用 tf.train.Saver()保存模型
2018/04/24 Python
Python中的字符串切片(截取字符串)的详解
2019/05/15 Python
python绘制规则网络图形实例
2019/12/09 Python
Python GUI编程学习笔记之tkinter事件绑定操作详解
2020/03/30 Python
Keras 使用 Lambda层详解
2020/06/10 Python
Ubuntu配置Pytorch on Graph (PoG)环境过程图解
2020/11/19 Python
python中实现词云图的示例
2020/12/19 Python
茵宝(Umbro)英国官方商店:英国足球服装生产商
2016/12/29 全球购物
简述安装Slackware Linux系统的过程
2012/05/08 面试题
心得体会怎么写
2013/12/30 职场文书
婚前保证书
2014/04/29 职场文书
张思德观后感
2015/06/09 职场文书
小学英语教学随笔
2015/08/14 职场文书
导游词之任弼时故居
2020/01/07 职场文书
探究Mysql模糊查询是否区分大小写
2021/06/11 MySQL