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 相关文章推荐
js点击更换背景颜色或图片的实例代码
Jun 25 Javascript
jquery向上向下取整适合分页查询
Sep 06 Javascript
JavaScript中对象property的读取和写入方法介绍
Dec 30 Javascript
JavaScript获取function所有参数名的方法
Oct 30 Javascript
javascript实现dom元素可拖动
Mar 21 Javascript
AngularJS 过滤器(自带和自建)详解
Sep 19 Javascript
Vue.js教程之计算属性
Nov 11 Javascript
jQuery插件FusionCharts绘制2D环饼图效果示例【附demo源码】
Apr 10 jQuery
简单实现jquery隔行变色
Nov 09 jQuery
Vue Element 分组+多选+可搜索Select选择器实现示例
Jul 23 Javascript
vue中使用vue-print.js实现多页打印
Mar 05 Javascript
vue+elementUI动态增加表单项并添加验证的代码详解
Dec 17 Vue.js
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
自制短波长线天线频率预选器 - 成功消除B2K之流的镜像
2021/03/02 无线电
Linux fgetcsv取得的数组元素为空字符串的解决方法
2011/11/25 PHP
PHP文章按日期(月日)SQL归档语句
2012/11/29 PHP
PHP错误Allowed memory size of 67108864 bytes exhausted的3种解决办法
2014/07/28 PHP
浅析Yii2 GridView 日期格式化并实现日期可搜索教程
2016/04/22 PHP
PHP简单获取网站百度搜索和搜狗搜索收录量的方法
2016/08/23 PHP
php中输出json对象的值(实现方法)
2018/03/07 PHP
img的onload的另类用法
2008/01/10 Javascript
JS的反射问题
2010/04/07 Javascript
关于jQuery中的end()使用方法
2011/07/10 Javascript
js实现浏览器的各种菜单命令比如打印、查看源文件等等
2013/10/24 Javascript
jquery操作HTML5 的data-*的用法实例分享
2014/08/17 Javascript
详解js中的apply与call的用法
2016/07/30 Javascript
微信小程序 开发之全局配置
2017/05/05 Javascript
JS鼠标3次点击事件实现代码及扩展思路
2017/09/12 Javascript
详解react native页面间传递数据的几种方式
2018/11/07 Javascript
JS实现继承的几种常用方式示例
2019/06/22 Javascript
微信小程序 简易计算器实现代码实例
2019/09/02 Javascript
vue实现手机端省市区区域选择
2019/09/27 Javascript
vue路由传参的基本实现方式小结【三种方式】
2020/02/05 Javascript
Vue中关闭弹窗组件时销毁并隐藏操作
2020/09/01 Javascript
[04:09]2018年度DOTA2社区贡献奖-完美盛典
2018/12/16 DOTA
用Python实现QQ游戏大家来找茬辅助工具
2014/09/14 Python
python 容器总结整理
2017/04/04 Python
python中文乱码不着急,先看懂字节和字符
2017/12/20 Python
Python将图片转换为字符画的方法
2020/06/16 Python
python 实现倒排索引的方法
2018/12/25 Python
Pycharm激活方法及详细教程(详细且实用)
2020/05/12 Python
Python+unittest+DDT实现数据驱动测试
2020/11/30 Python
解决HTML5手机端页面缩放的问题
2017/10/27 HTML / CSS
Bluebella美国官网:英国性感内衣品牌
2018/10/04 全球购物
企划专员岗位职责
2013/12/09 职场文书
乡镇党员群众路线教育实践活动对照检查材料思想汇报
2014/10/05 职场文书
拉贝日记观后感
2015/06/05 职场文书
pytorch 中nn.Dropout的使用说明
2021/05/20 Python
Element-ui Layout布局(Row和Col组件)的实现
2021/12/06 Vue.js