javascript 延迟加载技术(lazyload)简单实现


Posted in Javascript onJanuary 17, 2011

1.前言

懒加载技术(简称lazyload)并不是新技术, 它是js程序员对网页性能优化的一种方案.lazyload的核心是按需加载.在大型网站中都有lazyload的身影,例如谷歌的图片搜索页,迅雷首页,淘宝网,QQ空间等.因此掌握lazyload技术是个不错的选择,可惜jquery插件lazy load官网(http://www.appelsiini.net/projects/lazyload)称不支持新版浏览器。

2.lazyload在什么场合中应用比较合适?

涉及到图片,falsh资源 , iframe, 网页编辑器(类似FCK)等占用较大带宽,且这些模块暂且不在浏览器可视区内,因此可以使用lazyload在适当的时候加载该类资源.避免网页打开时加载过多资源,让用户等待太久.

3.如何实现lazyload?

lazyload的难点在如何在适当的时候加载用户需要的资源(这里用户需要的资源指该资源呈现在浏览器可视区域)。因此我们需要知道几点信息来确定目标是否已呈现在客户区,其中包括:

1.可视区域相对于浏览器顶端位置

2.待加载资源相对于浏览器顶端位置.

在得到以上两点数据后,通过如下函数,便可得出某对象是否在浏览器可视区域了.

//返回浏览器的可视区域位置 

 function getClient(){ 


 var l,t,w,h; 


 l = document.documentElement.scrollLeft || document.body.scrollLeft; 


 t = document.documentElement.scrollTop || document.body.scrollTop; 


 w = document.documentElement.clientWidth; 


 h = document.documentElement.clientHeight; 


 return {'left':l,'top':t,'width':w,'height':h} ; 

 } 

//返回待加载资源位置 

 function getSubClient(p){ 


 var l = 0,t = 0,w,h; 


 w = p.offsetWidth ; 


 h = p.offsetHeight; 


while(p.offsetParent){ 


l += p.offsetLeft ; 


 t += p.offsetTop ; 


 p = p.offsetParent; 

} 

return {'left':l,'top':t,'width':w,'height':h } ; 
}

其中 函数 getClient()返回浏览器客户区区域信息,getSubClient()返回目标模块区域信息。此时确定目标模块是否出现在客户区实际上是确定如上两个矩形是否相交.

//判断两个矩形是否相交,返回一个布尔值 

 function intens(rec1,rec2){ 


 var lc1,lc2,tc1,tc2,w1,h1; 


 lc1 = rec1.left + rec1.width / 2; 


 lc2 = rec2.left + rec2.width / 2; 


tc1 = rec1.top + rec1.height / 2 ; 


 tc2 = rec2.top + rec2.height / 2 ; 


 w1 = (rec1.width + rec2.width) / 2 ; 


 h1 = (rec1.height + rec2.height) / 2; 


 return Math.abs(lc1 - lc2) < w1 && Math.abs(tc1 - tc2) < h1 ; 

 }

现在基本上可以实现延时加载了,接下来,我们在 window.onscroll 事件中编写一些代码监控目标区域是否呈现在客户区.

<div style = "width:100px; height:3000px"></div> 

<div id = "d1" style = "width:50px; height:50px; background:red;position:absolute; top:1000px"> 

</div> 

 var d1 = document.getElementById("d1"); 

 window.onscroll = function(){ 

 
var prec1 = getClient(); 


var prec2 = getSubClient(d1); 


 if(intens(prec1,prec2)){ 

 

alert("true") 

   
} 

}

我们只需要在弹出窗口的地方加载我们需要的资源.

这里值得注意的是:目标对象呈现在客户区域时,会随着滚动而不断的弹出窗口.因此我们需要在弹出第一个窗口后取消对该区域的监测,这里用一个数组来收集需要监测的对象。还需要注意:因为onscroll事件和onresize事件都会改变游览器可视区域信息,因此在该类事件触发后需要重新计算目标对象是否在可视区域,这里用autocheck()函数实现.(迅雷首页的lazyload没有在onresize事件中重新计算目标对象是否在浏览器可视区域,因此如果先将浏览器窗口缩小到一定尺寸后滚动到需要加载图片的区域后点击最大化,图片加载不出来,呵呵,以后需要注意了).

增加元素:<div id = "d2" style = "width:50px; height:50px; background:blue;position:absolute; top:2500px">

//比较某个子区域是否呈现在浏览器区域 

function jiance(arr,prec1,callback){ 

 var prec2; 

 for(var i = arr.length - 1 ; i >= 0 ;i--){ 


 if(arr[i]){ 


 prec2 = getSubClient(arr[i]); 


 if(intens(prec1,prec2)){ 



callback(arr[i]); 



 //加载资源后,删除监测 


 
 delete arr[i]; 



} 


} 

 } 

} 

//检测目标对象是否出现在客户区 

function autocheck(){ 


 var prec1 = getClient(); 


jiance(arr,prec1,function(obj){ 



//加载资源... 


 alert(obj.innerHTML) 


}) 

} 

//子区域一 

 var d1 = document.getElementById("d1"); 

 //子区域二 

var d2 = document.getElementById("d2"); 

 //需要按需加载区域集合 

var arr = [d1,d2]; 

 window.onscroll = function(){ 


 //重新计算 


 autocheck(); 

} 

window.onresize = function(){ 


 //重新计算 


 autocheck(); 

}

现在我们只需要在弹窗的地方加载我们需要的资源了.源码就不贴出来了.如果需要的朋友,或着存在疑问的地方,可以联系我.

Javascript 相关文章推荐
javascript cookie操作类的实现代码小结附使用方法
Jun 02 Javascript
图片在浏览器中底部对齐 解决方法之一
Nov 30 Javascript
window.showModalDialog参数传递中含有特殊字符的处理方法
Jun 06 Javascript
jquery插件jquery倒计时插件分享
Dec 27 Javascript
JavaScript的常见兼容问题及相关解决方法(chrome/IE/firefox)
Dec 31 Javascript
javascript实现连续赋值
Aug 10 Javascript
Bootstrap组件学习之导航、标签、面包屑导航(精品)
May 17 Javascript
AngularJS中的包含详细介绍及实现示例
Jul 28 Javascript
微信小程序商城项目之商品属性分类(4)
Apr 17 Javascript
angular2中router路由跳转navigate的使用与刷新页面问题详解
May 07 Javascript
图片加载完成再执行事件的实例
Nov 16 Javascript
微信小程序实现分享商品海报功能
Sep 30 Javascript
关于COOKIE个数与大小的问题
Jan 17 #Javascript
js实现的跟随鼠标移动的时钟效果(中英文日期显示)
Jan 17 #Javascript
Jquery 插件开发笔记整理
Jan 17 #Javascript
JQuery学习笔记 nt-child的使用
Jan 17 #Javascript
Jquery知识点三 jquery表单对象操作
Jan 17 #Javascript
基于jquery的返回顶部效果(兼容IE6)
Jan 17 #Javascript
jquery+ajax每秒向后台发送请求数据然后返回页面的代码
Jan 17 #Javascript
You might like
虚拟主机中对PHP的特殊设置
2006/10/09 PHP
探讨fckeditor在Php中的配置详解
2013/06/08 PHP
ThinkPHP跳转页success及error模板实例教程
2014/07/17 PHP
php生成二维码时出现中文乱码的解决方法
2014/12/18 PHP
什么是PHP文件?如何打开PHP文件?
2017/06/27 PHP
JQery 渐变图片导航效果代码 漂亮
2010/01/01 Javascript
JavaScript 大数据相加的问题
2011/08/03 Javascript
基于BootStrap实现局部刷新分页实例代码
2016/08/08 Javascript
JavaScript实现定时页面跳转功能示例
2017/02/14 Javascript
JavaScript实现实时更新系统时间的实例代码
2017/04/04 Javascript
seajs实现强制刷新本地缓存的方法分析
2017/10/16 Javascript
微信小程序实现选项卡功能
2020/06/19 Javascript
JS实现点击拉拽轮播图pc端移动端适配
2018/09/05 Javascript
js实现录音上传功能
2019/11/22 Javascript
微信小程序实现按字母排列选择城市功能
2019/11/25 Javascript
[01:15:12]DOTA2上海特级锦标赛主赛事日 - 1 败者组第一轮#4Newbee VS CDEC
2016/03/03 DOTA
Python+Opencv识别两张相似图片
2020/03/23 Python
python如何查看微信消息撤回
2018/11/27 Python
python matplotlib实现将图例放在图外
2020/04/17 Python
python+pygame实现坦克大战小游戏的示例代码(可以自定义子弹速度)
2020/08/11 Python
Python Selenium实现无可视化界面过程解析
2020/08/25 Python
香港礼品网站:GiftU eshop
2017/09/01 全球购物
GOOD AMERICAN官网:为曲线性感而设计
2017/12/28 全球购物
美国婴儿和儿童家具网上商店:ABaby.com
2018/07/02 全球购物
以下为Windows NT 下的32 位C++程序,请计算sizeof 的值
2016/12/07 面试题
软件测试工程师笔试题带答案
2015/03/27 面试题
人力资源经理自我评价
2014/01/04 职场文书
2014年党员公开承诺践诺书
2014/03/25 职场文书
公务员培的训心得体会
2014/09/01 职场文书
写给医生的感谢信
2015/01/22 职场文书
收银员岗位职责
2015/02/03 职场文书
高中班主任心得体会
2016/01/07 职场文书
Python编写可视化界面的全过程(Python+PyCharm+PyQt)
2021/05/17 Python
Tomcat项目启动失败的原因和解决办法
2022/04/20 Servers
提高系统的吞吐量解决数据库重复写入问题
2022/04/23 MySQL
Python开发五子棋小游戏
2022/04/28 Python