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 相关文章推荐
关于onScroll事件在IE6下每次滚动触发三次bug说明
Sep 21 Javascript
js循环改变div颜色具体方法
Jun 25 Javascript
jquery取消选择select下拉框示例代码
Feb 22 Javascript
如何防止JavaScript自动插入分号
Nov 05 Javascript
JS实现的打字机效果完整实例
Jun 20 Javascript
利用css+原生js制作简单的钟表
Apr 07 Javascript
详解基于angular路由的requireJs按需加载js
Jan 20 Javascript
ajax接收后台数据在html页面显示
Feb 19 Javascript
js学习总结之DOM2兼容处理顺序问题的解决方法
Jul 27 Javascript
Vue项目使用CDN优化首屏加载问题
Apr 01 Javascript
vue 动态给每个页面添加title、关键词和描述的方法
Aug 28 Javascript
vue 如何从单页应用改造成多页应用
Oct 23 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递归返回值时出现的问题解决办法
2013/02/19 PHP
解析php中如何调用用户自定义函数
2013/08/06 PHP
phpexcel导入excel数据使用方法实例
2013/12/24 PHP
PHP分享图片的生成方法
2018/04/25 PHP
javascript使用smipleChart实现简单图表
2015/01/02 Javascript
深入浅析react native es6语法
2015/12/09 Javascript
基于jquery实现轮播焦点图插件
2016/03/31 Javascript
jQuery中的基本选择器用法学习教程
2016/04/14 Javascript
AngularJS ng-bind 指令简单实现
2016/07/30 Javascript
Canvas + JavaScript 制作图片粒子效果
2017/02/08 Javascript
基于Vue2.0+ElementUI实现表格翻页功能
2017/10/23 Javascript
原生js实现淘宝放大镜效果
2020/10/28 Javascript
iview form清除校验状态的实现
2019/09/19 Javascript
[01:02]DOTA2辉夜杯决赛日 CDEC.Y对阵VG赛前花絮
2015/12/27 DOTA
python通过ftplib登录到ftp服务器的方法
2015/05/08 Python
通过Python来使用七牛云存储的方法详解
2015/08/07 Python
python发送邮件实例分享
2017/07/28 Python
Python实现KNN邻近算法
2021/01/28 Python
浅谈dataframe中更改列属性的方法
2018/07/10 Python
python3实现表白神器
2019/04/09 Python
基于YUV 数据格式详解及python实现方式
2019/12/09 Python
Pandas 解决dataframe的一列进行向下顺移问题
2019/12/27 Python
django迁移文件migrations的实现
2020/03/31 Python
使用Python制作一个数据预处理小工具(多种操作一键完成)
2021/02/07 Python
HTML5地理定位实例
2014/10/15 HTML / CSS
英国汽车和货车租赁网站:Hertz英国
2016/09/02 全球购物
澳大利亚家具和家居用品购物网站:Zanui
2018/12/29 全球购物
Perfume’s Club德国官网:在线购买香水
2019/04/08 全球购物
亚洲最大的运动鞋寄售店:KicksCrew
2020/11/26 全球购物
下述程序的作用是计算机数组中的最大元素值及其下标
2012/11/26 面试题
急诊科护士自我鉴定
2013/10/14 职场文书
《认识钟表》教学反思
2016/02/16 职场文书
2019最新激励员工口号大全!
2019/06/28 职场文书
导游词之无锡丝业博物馆
2019/11/12 职场文书
python 实现图与图之间的间距调整subplots_adjust
2021/05/21 Python
利用python调用摄像头的实例分析
2021/06/07 Python