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 DOM 操作实现代码
Aug 01 Javascript
js遍历td tr等html元素
Dec 13 Javascript
jQuery不间断滚动效果(模拟百度新闻支持文字/图片/垂直滚动)
Feb 05 Javascript
深入理解Javascript中this的作用域
Aug 12 Javascript
Javascript中实现trim()函数的两种方法
Feb 04 Javascript
js+html5实现的自由落体运动效果代码
Jan 28 Javascript
JavaScript 数组的深度复制解析
Nov 02 Javascript
jQuery中的siblings()是什么意思(推荐)
Dec 29 Javascript
基于JavaScript实现焦点图轮播效果
Mar 27 Javascript
Vue学习之路之登录注册实例代码
Jul 06 Javascript
vue slots 组件的组合/分发实例
Sep 06 Javascript
Vuejs学习笔记之使用指令v-model完成表单的数据双向绑定
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
如何使用动态共享对象的模式来安装PHP
2006/10/09 PHP
实现dedecms全站URL静态化改造的代码
2007/03/29 PHP
php代码架构的八点注意事项
2016/01/25 PHP
Android App中DrawerLayout抽屉效果的菜单编写实例
2016/03/21 PHP
php判断str字符串是否是xml格式数据的方法示例
2017/07/26 PHP
php数组和链表的区别总结
2019/09/20 PHP
PHP设计模式(五)适配器模式Adapter实例详解【结构型】
2020/05/02 PHP
JS左右无缝滚动(一般方法+面向对象方法)
2012/08/17 Javascript
JavaScript去除空格的三种方法(正则/传参函数/trim)
2013/02/06 Javascript
常用的几段javascript代码分享
2014/03/25 Javascript
js简单实现表单中点击按钮动态增加输入框数量的方法
2015/08/18 Javascript
基于Bootstrap使用jQuery实现简单可编辑表格
2016/05/04 Javascript
Express进阶之log4js实用入门指南
2018/02/10 Javascript
详解从NodeJS搭建中间层再谈前后端分离
2018/11/13 NodeJs
详解基于Vue/React项目的移动端适配方案
2019/08/23 Javascript
ES6字符串的扩展实例
2020/12/21 Javascript
[46:14]VGJ.T vs Liquid 2018国际邀请赛小组赛BO2 第一场 8.19
2018/08/21 DOTA
python命令行参数sys.argv使用示例
2014/01/28 Python
python解析html开发库pyquery使用方法
2014/02/07 Python
python实现颜色rgb和hex相互转换的函数
2015/03/19 Python
Python httplib模块使用实例
2015/04/11 Python
Python3爬取英雄联盟英雄皮肤大图实例代码
2018/11/14 Python
python是否适合网页编程详解
2019/10/04 Python
python中time库的实例使用方法
2019/10/31 Python
解决django-xadmin列表页filter关联对象搜索问题
2019/11/15 Python
Python+PyQt5实现灭霸响指功能
2020/05/25 Python
在 Windows 下搭建高效的 django 开发环境的详细教程
2020/07/27 Python
CSS3中伪元素::before和::after的用法示例
2017/09/18 HTML / CSS
另类冲刺标语
2014/06/24 职场文书
素质教育标语
2014/06/27 职场文书
新学期开学标语
2014/06/30 职场文书
党的群众路线对照检查材料(个人)
2014/09/24 职场文书
新农村建设指导员工作总结
2015/08/13 职场文书
导游词之北京明十三陵
2019/10/28 职场文书
JavaGUI模仿QQ聊天功能完整版
2021/07/04 Java/Android
优化Mysql查询的示例
2022/04/26 MySQL