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 函数式编程的原理
Oct 16 Javascript
锋利的jQuery jQuery中的DOM操作
Mar 21 Javascript
跟着JQuery API学Jquery 之二 属性
Apr 09 Javascript
详谈 Jquery Ajax异步处理Json数据.
Sep 09 Javascript
优化Jquery,提升网页加载速度
Nov 14 Javascript
iScroll中事件点击触发两次解决方案
Mar 11 Javascript
avalon js实现仿微博拖动图片排序
Aug 14 Javascript
Jquery1.9.1源码分析系列(十五)动画处理之外篇
Dec 04 Javascript
分享12个实用的jQuery代码片段
Mar 09 Javascript
jquery mobile界面数据刷新的实现方法
May 28 Javascript
jQuery Easyui学习教程之实现datagrid在没有数据时显示相关提示内容
Jul 09 Javascript
基于angular2 的 http服务封装的实例代码
Jun 29 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
多文件上传的例子
2006/10/09 PHP
php 引用(&amp;)详解
2009/11/20 PHP
在PHP中实现Javascript的escape()函数代码
2010/08/08 PHP
Win下如何安装PHP的APC拓展
2013/08/07 PHP
PHP MySql增删改查的简单实例
2016/06/21 PHP
PHP递归遍历指定文件夹内的文件实现方法
2016/11/15 PHP
Smarty模板变量与调节器实例详解
2019/07/20 PHP
laravel框架实现去掉URL中index.php的方法
2019/10/12 PHP
JCalendar 日历控件 v1.0 beta[兼容IE&amp;Firefox] 有文档和例子
2007/05/30 Javascript
JavaScript中将一个值转换为字符串的方法分析[译]
2012/09/21 Javascript
Js 代码中,ajax请求地址后加随机数防止浏览器缓存的原因
2013/05/07 Javascript
javascript使用正则控制input输入框允许输入的值方法大全
2014/06/19 Javascript
javascript中字符串拼接详解
2014/09/26 Javascript
JS获得选取checkbox整行数据的方法
2015/01/28 Javascript
Bootstrap每天必学之简单入门
2015/11/19 Javascript
jQuery实现QQ空间汉字转拼音功能示例
2017/07/10 jQuery
vue实现仿淘宝结账页面实例代码
2017/11/08 Javascript
vue2.0项目实现路由跳转的方法详解
2018/06/21 Javascript
JavaScript实现轮播图片完整代码
2020/03/07 Javascript
Python设计模式之代理模式实例
2014/04/26 Python
Python编程实现控制cmd命令行显示颜色的方法示例
2017/08/14 Python
python距离测量的方法
2018/03/06 Python
Python实现按当前日期(年、月、日)创建多级目录的方法
2018/04/26 Python
pandas将numpy数组写入到csv的实例
2018/07/04 Python
python opencv实现图片旋转矩形分割
2018/07/26 Python
Pycharm取消py脚本中SQL识别的方法
2018/11/29 Python
美国踏板车和轻便摩托车销售网站:Mega Motor Madness
2020/02/26 全球购物
历史学专业毕业生求职信
2013/09/27 职场文书
计算机专业推荐信范文
2013/11/20 职场文书
学前教育学生自荐信范文
2013/12/31 职场文书
2014年餐厅服务员工作总结
2014/11/18 职场文书
销售内勤岗位职责
2015/02/10 职场文书
党课主持词大全
2015/06/30 职场文书
初二数学教学反思
2016/02/17 职场文书
2016年“我们的节日·中秋节”活动总结
2016/04/05 职场文书
Nginx URL重写rewrite机制原理及使用实例
2021/04/01 Servers