JS图片延迟加载分析及简单的demo
JS图片延迟加载
图片延迟加载也称 "懒加载",通常应用于图片比较多的网页,比如 "美丽说首页","蘑菇街"等一些导购网站上用的比较多,或者淘宝,京东等电子商务网站上也用的比较多,因为页面加载时候 假如我们没有用延迟加载的话 那么页面上很多图片,首先要发n多个请求,性能肯定不怎么好,而我们用延迟加载技术,页面打开时候 只加载第一屏数据,第二屏以上都用延迟加载 滚动的时候进行加载,这样的话 假如页面不管他有n屏的话 那么我们只管加载第一屏的数据,后面不做操作。这样就可以显著的提高页面的加载速度,提升用户体验。且更小的并发请求也可以减轻服务器的压力,而且如果用户只浏览首屏的话,还可以节省流量(手机客户端应该用的比较多,减少用户流量)。
延迟加载的原理是?
我这边原理是先在img src中放一张占位符图片,而真实的图片地址存放在相对应一个属性 data-img(后缀img可以自定义)中,这样的话 那么页面加载的时候 只加载src地址 不会对属性的图片真正地址加载,滚动时候判断 待加载的资源相对于浏览器顶端的距离 <= 可视区域相对于浏览器顶端的距离 如果为true的话 则把相对应的data-img值赋值给src 否则不加载。
先看看JSFiddle的demo效果
如果最外层容器是window的话 那么请看这个demo demo链接
如果自己定义了最外层容器的话 那么请看这个demo demo链接
可配置的参数如下:
container | window,容器 默认为window |
threshold | 灵敏度。默认为 0 表示当图片出现在显示区域中的立即加载显示;设为整数表示图片距离 x 像素进入显示区域时进行加载;设为负数表示图片进入显示区域 x 像素时进行加载。 |
event | 默认为scroll(滚动) |
effect | 默认为fadeIn 也可以为fadeIn, slideDown 等 jQuery 自带的效果 |
effectspeed | 1000, effect的时间 默认为1000(毫秒) |
suffix | 'img', img属性 默认以data-img 也可以自定义后缀 |
skip_invisible | 如果img标签为隐藏的 那么不强制加载(比如display:none等) 默认为true |
代码简单的分析下:
1.页面初始化init时候 只处理一个滚动事件:如下调用update方法:

init: function(options){
this.config = $.extend(this.config, options || {});
var self = this,
_config = self.config,
_cache = self.cache;
// 滚动时(或者其他事件) 触发事件
$(_config.container).unbind(_config.event);
$(_config.container).bind(_config.event,function(){
self._update();
});
}

2.update方法先判断下 容器是否是window还是自定义容器。且对向下滚动及向右滚动进行了一下处理。接着调用_eachImg这个方法。代码如下:

_update:function(){
var self = this,
_config = self.config,
_cache = self.cache;
if(_config.container === window) { $('img').each(function(index,item){
// 如果图片隐藏的 那么不强制加载
if(_config.skip_invisible && !$('img').is(":visible")) {
return;
}
if (self._abovethetop(item) ||
self._leftofbegin(item)) {
// 什么都不处理
} else if (self._belowthefold(item) &&
self._belowthefold(item)) {
self._eachImg(item);
}
}) }else {
$('img',$(_config.container)).each(function(index,item){
// 如果图片隐藏的 那么不强制加载
if(_config.skip_invisible && !$('img').is(":visible")) {
return;
}
if (self._abovethetop(item) ||
self._leftofbegin(item)) { } else if (self._belowthefold(item) &&
self._rightoffold(item)) {
self._eachImg(item);
} })
} },

3.在调用eachImg方法之前 先判断向下滚动或者向右滚动 元素是否在可视区域内 如在 则调用eachImg方法 把对应的data-img赋值给src 否则 反之。
HTML代码如下:

<img src="data:images/grey.gif" data-img ="http://m3.img.libdd.com/farm4/d/2014/0111/18/3256C6587D94BDF9E9908908CAB6C5FD_B500_900_500_375.jpeg" width="800" height="600" isload="false"><br/>
<img src="data:images/grey.gif" data-img ="http://m3.img.libdd.com/farm4/d/2014/0111/18/23CC5BDD3730A819E498B703A40DE5CF_B250_400_250_187.jpeg" width="800" height="600" isload="false"><br/>
<img src="data:images/grey.gif" data-img ="http://m3.img.libdd.com/farm4/d/2014/0111/18/33F69B61E6671E4F6623F0D1084C42A8_B250_400_250_187.jpeg" width="800" height="600" isload="false"><br/>
<img src="data:images/grey.gif" data-img ="http://m3.img.libdd.com/farm5/d/2014/0111/18/7B87F0A2209D234D2AB907C62946A7FE_B250_400_250_187.jpeg" width="800" height="600" isload="false"><br/>
<img src="data:images/grey.gif" data-img ="http://m2.img.libdd.com/farm5/d/2014/0111/18/C37405D8DBC8D1BF69A9C894C32FA4DA_B250_400_250_187.jpeg" width="800" height="600" isload="false"><br/>
<img src="data:images/grey.gif" data-img ="http://m1.img.libdd.com/farm5/d/2014/0111/18/1433297A651DA0329E866FD2D2776C7F_B250_400_250_187.jpeg" width="800" height="600" isload="false">

JS所有代码如下:

/**
* JS图片延迟加载
* @constructor {DataLazyLoad}
* @param {options} 对象传参
* @time 2014-1-10
*/
/*
* 延迟加载的原理:滚动时:待加载的资源相对于游览器顶端的距离 - threshold <= 可视区域相对于浏览器顶端的距离 true 就加载
* 否则的话 不加载
*/
function DataLazyLoad(options){ this.config = { container : window, //容器 默认为window
threshold : 0, // 离多少像素渲染图片
event : 'scroll', // 默认为scroll(滚动)
effect : 'fadeIn', // 默认为fadeIn 也可以为fadeIn, slideDown 等 jQuery 自带的效果
effectspeed : 1000, // 时间
suffix : 'img', // img属性 默认以data-img 也可以自定义后缀
skip_invisible : true // 如果img标签为隐藏的 那么不强制加载
}; this.cache = {}; this.init(options);
} DataLazyLoad.prototype = { init: function(options){ this.config = $.extend(this.config, options || {});
var self = this,
_config = self.config,
_cache = self.cache; // 滚动时(或者其他事件) 触发事件
$(_config.container).unbind(_config.event);
$(_config.container).bind(_config.event,function(){
self._update();
});
},
/*
* 加载对应的图片
*/
_eachImg: function(item) {
var self = this,
_config = self.config,
_cache = self.cache; if($(item).attr('isload') == 'false') {
var dataImg = $(item).attr('data-'+_config.suffix),
src = $(item).attr('src');
$(item).hide();
$(item).attr('src',dataImg);
$(item).attr('data-'+_config.suffix,'');
$(item)[_config.effect](_config.effectspeed);
$(item).attr('isload','true');
}
},
_update:function(){
var self = this,
_config = self.config,
_cache = self.cache;
if(_config.container === window) { $('img').each(function(index,item){
// 如果图片隐藏的 那么不强制加载
if(_config.skip_invisible && !$('img').is(":visible")) {
return;
}
if (self._abovethetop(item) ||
self._leftofbegin(item)) {
// 什么都不处理
} else if (self._belowthefold(item) &&
self._belowthefold(item)) {
self._eachImg(item);
}
}) }else {
$('img',$(_config.container)).each(function(index,item){
// 如果图片隐藏的 那么不强制加载
if(_config.skip_invisible && !$('img').is(":visible")) {
return;
}
if (self._abovethetop(item) ||
self._leftofbegin(item)) { } else if (self._belowthefold(item) &&
self._rightoffold(item)) {
self._eachImg(item);
} })
} },
/*
* 往下滚动时 判断待加载的元素是否在可视区域内
* @return {Boolean}
*/
_belowthefold: function(elem){
var self = this,
_config = self.config;
var fold;
if(_config.container === window) {
fold = $(window).height() + $(window).scrollTop();
}else {
fold = $(_config.container).offset().top + $(_config.container).height();
} return fold >= $(elem).offset().top - _config.threshold;
},
/*
* 往右滚动时 判断待加载的元素是否在可视区域内
* @return {Boolean}
*/
_rightoffold: function(elem){
var self = this,
_config = self.config;
var fold;
if(_config.container === window) {
fold = $(window).width() + $(window).scrollLeft();
}else {
fold = $(_config.container).offset().left + $(_config.container).width();
} return fold >= $(elem).offset().left - _config.threshold;
},
/*
* 往上滚动
* @return {Boolean}
*/
_abovethetop: function(elem){
var self = this,
_config = self.config;
var fold;
if(_config.container === window) {
fold = $(window).scrollTop();
}else {
fold = $(_config.container).offset().top;
}
return fold >= $(elem).offset().top + _config.threshold + $(elem).height();
},
/*
* 往左滚动
* @return {Boolean}
*/
_leftofbegin: function(elem) {
var self = this,
_config = self.config;
var fold; if (_config.container === window) {
fold = $(window).scrollLeft();
} else {
fold = $(_config.container).offset().left;
}
return fold >= $(elem).offset().left + _config.threshold + $(elem).width();
} }; // 初始化的方式
$(function(){ var datalazy = new DataLazyLoad({
container: '#demo'
});
});

初始化方式如下:
// 初始化的方式
$(function(){
var datalazy = new DataLazyLoad({
container: '#demo'
});
});
也可以根据自己自动配置。
JS图片延迟加载分析及简单的demo的更多相关文章
- js图片延迟加载
什么是图片延迟加载? 也叫懒加载. 当页面有多屏的时候,页面中的图片比较多. 那么,在页面载入完毕的时候,并不会把所有的图片都加载进来. 而是当用户拖动滚动条的时候,图片要进入用户的视野了,才开始加载 ...
- jquery.lazyload.js 图片延迟加载
当做网页的时候,特别是整个网页展示图片较多的时候,用到图片延迟效果是很好的 使用方法也非常简单. 1.在网页任何位置(一般是在</body>前面)加上如下代码(注意<script&g ...
- jquery.lazyload.js图片延迟加载
转:http://www.jb51.net/article/50273.htm 这篇文章主要介绍了Jquery图片延迟加载插件jquery.lazyload.js的使用方法,需要的朋友可以参考下 ...
- 一个简单而实用的JQ插件——lazyload.js图片延迟加载插件
前 言 Cherish 看多了炫酷的插件之后再来看这么一个小清新的东西,是不是突然感觉JQ插件感觉很友好了,简单强大最重要的是实用. 这篇文章将详细讲解一下lazyload.js的用法 lazy ...
- jquery.lazyload.js图片延迟加载(懒加载)--转载
一.插件介绍 jquery.lazyload.js 是一个用 JavaScript 编写的jQuery 插件. 它可以延迟加载长页面中的图片. 在浏览器可视区域外的图片不会被载入, 直到用户将页面滚动 ...
- js图片延迟加载如何实现
这里延迟加载的意思是,拖动滚动条时,在图片出现在浏览器显示区域后才加载显示. 大概的实现方式是: 在页面的load没有触发之前,把所有的指定id的元素内的img放入到imgs中,将所有的图片的sr ...
- js图片拖放原理(很简单,不是框架,入门基础)
<html> <meta> <script src='jquery-1.8.3.min.js'></script> <script> /* ...
- JS实现移动端图片延迟加载
图片延迟加载常见的有,jquery.lazyload.js,原生JS实现的echo.js.但是都是必须给图片设置宽高. 因为项目是移动端,而且无法在加载前知道图片的宽高,所以,只好自己写了一个. 既然 ...
- JS图片预加载插件
在开发H5项目中有时候会遇到要加载大量图片的情况,利用预加载技术可以提高用户浏览时的体验. 1)概念:懒加载也叫延迟加载:JS图片延迟加载,延迟加载图片或符合某些条件时才加载某些图片.预加载:提前加载 ...
随机推荐
- 浅谈php对api开发的作用
最近正在做一个手机APP的服务端API开发,虽然是基于Ruby on Rails的,做的也不太专业,不过大致相通,希望能够给你一些启发. 首先,如果是比较简单的手机APP,例如新闻客户端这样的不会涉及 ...
- 使用.NET FrameWork获取CPU,内存使用率以及磁盘空间
在以前,我们想获取CPU,内存等信息就不得不借助win32 API来实现.但现在,.NET FrameWork已经把这些API封装到.NET类库中了,所以我们可以借助.NET类库很轻松的获取这些信息. ...
- --hdu 1231 最大连续子序列(动态规划)
AC code: #include<stdio.h> int a[100005]; int main(void) { int n,i; int sum,maxn,tem,s,e,flag; ...
- mysql PDO的使用
原文链接:http://www.cnblogs.com/xiaochaohuashengmi/archive/2010/08/12/1797753.html
- 安装TFS2008最终版(转载)
一.安装操作系统:windows server 2003 + Sp2具体步骤: 1.安装windows server 2003时选用工作组(默认为workgroup).由于在工作组环境中部署,因此使用 ...
- 什么是RST包,什么是三次握手,什么是四次握手 ---请进
一.RST包.本人学习后总结:RST包用于强制关闭TCP链接. TCP连接关闭的正常方法是四次握手.但四次握手不是关闭TCP连接的唯一方法. 有时,如果主机需要尽快关闭连接(或连接超时,端口或主机不可 ...
- MD5 Message Digest Algorithm MD5(中文名为消息摘要算法第五版)
MD5 编辑 Message Digest Algorithm MD5(中文名为消息摘要算法第五版)为计算机安全领域广泛使用的一种散列函数,用以提供消息的完整性保护.该算法的文件号为RFC 1321( ...
- jquery中$.ajax
$.ajax({ type : 'post', url : '/edm/testEmail.php', data: {tId:tId, sId:sId ,testEmail:testEmail}, d ...
- 在rails下新建表
(文章都是从我的个人主页上粘贴过来的,大家也可以访问我的主页 www.iwangzheng.com) 今天需要新建表,以下是建表语句 rails generate scaffold users ema ...
- 搭建自己的ngrok服务
转载:http://tonybai.com/2015/03/14/selfhost-ngrok-service/ 在国内开发微信公众号.企业号以及做前端开发的朋友想必对ngrok都不陌生吧,就目前来看 ...