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 事件参考手册
Dec 24 Javascript
14个有用的Jquery技巧分享
Jan 08 Javascript
JS使用post提交的两种方式
Dec 03 Javascript
快速掌握Node.js中setTimeout和setInterval的使用方法
Mar 21 Javascript
JS在onclientclick里如何控制onclick的执行
May 30 Javascript
大白话讲解JavaScript的Promise
Apr 06 Javascript
JS简单判断滚动条的滚动方向实现方法
Apr 28 Javascript
AngularJS动态绑定ng-options的ng-model实例代码
Jun 21 Javascript
ES6新增数据结构WeakSet的用法详解
Aug 07 Javascript
jQuery 操作 HTML 元素和属性的方法
Nov 12 jQuery
Vue源码解析之数据响应系统的使用
Apr 24 Javascript
Vue 引入AMap高德地图的实现代码
Apr 29 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
超神学院:天使彦公认最美的三个视角,网友:我的天使快下凡吧!
2020/03/02 国漫
一个好用的分页函数
2006/11/16 PHP
PHP添加Xdebug扩展的方法
2014/02/12 PHP
PHP Cookie学习笔记
2016/08/23 PHP
YII2框架中使用RBAC对模块,控制器,方法的权限控制及规则的使用示例
2020/03/18 PHP
js 加载时自动调整图片大小
2008/05/28 Javascript
ASP.NET jQuery 实例8 (动态添加内容到DropDownList)
2012/02/03 Javascript
简略说明Javascript中的= =(等于)与= = =(全等于)区别
2013/04/16 Javascript
js和as的稳定传值问题解决
2013/07/14 Javascript
基于NodeJS的前后端分离的思考与实践(二)模版探索
2014/09/26 NodeJs
Angular2学习笔记——详解路由器模型(Router)
2016/12/02 Javascript
AngularJS服务service用法总结
2016/12/13 Javascript
Vue 进阶教程之v-model详解
2017/05/06 Javascript
vue使用vue-i18n实现国际化的实现代码
2018/04/08 Javascript
在vue中使用vue-echarts-v3的实例代码
2018/09/13 Javascript
ES6使用新特性Proxy实现的数据绑定功能实例
2020/05/11 Javascript
Angular处理未可知异常错误的方法详解
2021/01/17 Javascript
JavaScript 生成唯一ID的几种方式
2021/02/19 Javascript
python模拟表单提交登录图书馆
2018/04/27 Python
Python requests模块基础使用方法实例及高级应用(自动登陆,抓取网页源码)实例详解
2020/02/14 Python
解析python 中/ 和 % 和 //(地板除)
2020/06/28 Python
详解Anaconda安装tensorflow报错问题解决方法
2020/11/01 Python
css3实现一个div设置多张背景图片及background-image属性实例演示
2017/08/10 HTML / CSS
CSS3 display知识详解
2015/11/25 HTML / CSS
维也纳通行证:Vienna PASS
2019/07/18 全球购物
初中生三年学习生活的自我评价
2013/11/03 职场文书
函授毕业生自我鉴定
2013/11/06 职场文书
文言文形式的学生求职信
2013/12/03 职场文书
大学生社会实践评语
2014/04/25 职场文书
社区清明节活动总结
2014/07/04 职场文书
超市创意活动方案
2014/08/15 职场文书
活动总结模板大全
2015/05/11 职场文书
2016教师节感恩话语
2015/12/09 职场文书
2019新员工心得体会
2019/06/25 职场文书
Oracle创建只读账号的详细步骤
2021/06/07 Oracle
SQL Server数据库备份和恢复数据库的全过程
2022/06/14 SQL Server