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 相关文章推荐
推荐11款jQuery开发的复选框和单选框美化插件
Aug 02 Javascript
jQuery EasyUI API 中文文档 - NumberSpinner数值微调器使用介绍
Oct 21 Javascript
为EasyUI的Tab标签添加右键菜单的方法
Jul 14 Javascript
Redis基本知识、安装、部署、配置笔记
Mar 05 Javascript
jQuery实现高亮显示的方法
Mar 10 Javascript
JavaScript中的this关键字使用方法总结
Mar 13 Javascript
js判断日期时间有效性的方法
Oct 24 Javascript
AngularJs篇:使用AngularJs打造一个简易权限系统的实现代码
Dec 26 Javascript
vue生成token并保存到本地存储中
Jul 17 Javascript
JS设置自定义快捷键并实现图片上下左右移动
Oct 17 Javascript
JavaScript实现随机点名器
Mar 25 Javascript
从零开始在vue-cli4配置自适应vw布局的实现
Jun 08 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
绿山咖啡和蓝山咖啡
2021/03/04 新手入门
在PHP中实现Javascript的escape()函数代码
2010/08/08 PHP
PHP过滤黑名单关键字的方法
2014/12/01 PHP
PHP实现一维数组转二维数组的方法
2015/02/25 PHP
一个javascript参数的小问题
2008/03/02 Javascript
JQuery入门—JQuery程序的代码风格详细介绍
2013/01/03 Javascript
6款新颖的jQuery和CSS3进度条插件推荐
2013/03/05 Javascript
JS 如何获取radio选中后的值及不选择取radio的值
2013/10/28 Javascript
js插件设置innerHTML时在IE8下提示“未知运行时错误”解决方法
2015/04/25 Javascript
使用AngularJS制作一个简单的RSS阅读器的教程
2015/06/18 Javascript
node.js调用C++开发的模块实例
2015/07/03 Javascript
JQuery fileupload插件实现文件上传功能
2016/03/18 Javascript
深入浅析JSON.parse()、JSON.stringify()和eval()的作用详解
2016/04/03 Javascript
去除字符串左右两边的空格(实现代码)
2016/05/12 Javascript
浅谈js停止事件冒泡 阻止浏览器的默认行为(阻止超连接 #)
2017/02/08 Javascript
详解Vue.js基于$.ajax获取数据并与组件的data绑定
2017/05/26 Javascript
nodejs初始化init的示例代码
2018/10/10 NodeJs
jQuery+Datatables实现表格批量删除功能【推荐】
2018/10/24 jQuery
JS实现烟花爆炸效果
2020/03/10 Javascript
谈谈node.js中的模块系统
2020/09/01 Javascript
Python实现通讯录功能
2018/02/22 Python
使用anaconda的pip安装第三方python包的操作步骤
2018/06/11 Python
自学python的建议和周期预算
2019/01/30 Python
Python多线程模块Threading用法示例小结
2019/11/09 Python
实现ECharts双Y轴左右刻度线一致的例子
2020/05/16 Python
北美大型运动类产品商城:Champs Sports
2017/01/12 全球购物
美国知名日用品连锁超市:Dollar General(多来店)
2017/01/14 全球购物
美国家居装饰店:Pier 1
2019/09/04 全球购物
联想智利官方网站:Lenovo Chile
2020/06/03 全球购物
大学生标准推荐信范文
2013/11/25 职场文书
饭店工作计划书
2014/01/10 职场文书
绩效管理实施方案
2014/03/19 职场文书
医院党的群众路线教育实践活动领导班子对照检查材料
2014/09/25 职场文书
行政主管岗位职责范本
2015/04/09 职场文书
2015年中秋晚会主持词
2015/07/01 职场文书
《英雄联盟》2022日蚀、月蚀皮肤演示 黑潮亚索曝光
2022/04/13 其他游戏