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 相关文章推荐
jquery实现html页面 div 假分页有原理有代码
Sep 06 Javascript
iframe里使用JavaScript控制主页转向的方法
Apr 03 Javascript
jQuery基于ajax实现带动画效果无刷新柱状图投票代码
Aug 10 Javascript
JavaScript实现带箭头标识的多级下拉菜单效果
Aug 27 Javascript
JavaScript中的事件委托及好处
Jul 12 Javascript
Django1.7+JQuery+Ajax验证用户注册集成小例子
Apr 08 jQuery
JS实现的全排列组合算法示例
Oct 09 Javascript
Vue2 SSR渲染根据不同页面修改 meta
Nov 20 Javascript
jQuery实现DIV响应鼠标滑过由下向上展开效果示例【测试可用】
Apr 26 jQuery
关于微信公众号开发无法支付的问题解决
Dec 28 Javascript
详细分析vue响应式原理
Jun 22 Javascript
微信小程序轮播图swiper代码详解
Dec 01 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模拟SQL Server的两个日期处理函数
2006/10/09 PHP
PHP整合七牛实现上传文件
2015/07/03 PHP
Zend Framework缓存Cache用法简单实例
2016/03/19 PHP
php实现批量删除挂马文件及批量替换页面内容完整实例
2016/07/08 PHP
php实现批量修改文件名称的方法
2016/07/23 PHP
laravel-admin的多级联动方法
2019/09/30 PHP
用JavaScript对JSON进行模式匹配 (Part 2 - 实现)
2010/07/17 Javascript
javascript oop开发滑动(slide)菜单控件
2010/08/25 Javascript
JavaScript.The.Good.Parts阅读笔记(一)假值与===运算符
2010/11/16 Javascript
JavaScript之自定义类型
2012/05/04 Javascript
Jquery多选框互相内容交换的实例代码
2013/07/04 Javascript
jquery制作图片时钟特效
2020/03/30 Javascript
微信小程序之拖拽排序(代码分享)
2017/01/21 Javascript
JavaScript Drum Kit 指南(纯 JS 模拟敲鼓效果)
2017/07/23 Javascript
vue中element 上传功能的实现思路
2018/07/06 Javascript
浅谈微信JS-SDK 微信分享接口开发(介绍版)
2018/08/15 Javascript
OpenLayers3实现对地图的基本操作
2020/09/28 Javascript
Vue2.x和Vue3.x的双向绑定原理详解
2020/11/05 Javascript
Python实现批量检测HTTP服务的状态
2016/10/27 Python
使用python调用zxing库生成二维码图片详解
2017/01/10 Python
详解python3中的真值测试
2018/08/13 Python
python3 实现一行输入,空格隔开的示例
2018/11/14 Python
Pyqt5 实现跳转界面并关闭当前界面的方法
2019/06/19 Python
python+openCV利用摄像头实现人员活动检测
2019/06/22 Python
python+numpy实现的基本矩阵操作示例
2019/07/19 Python
让你的Python代码实现类型提示功能
2019/11/19 Python
wxPython多个窗口的基本结构
2019/11/19 Python
css3简单练习实现遨游浏览器logo的绘制
2013/01/30 HTML / CSS
全球最大的在线橄榄球商店:Lovell Rugby
2018/05/20 全球购物
异常和异常类的概念
2014/09/12 面试题
工作保证书范文
2014/04/29 职场文书
电子信息专业应届生自荐信
2014/06/04 职场文书
幼儿园教师师德师风演讲稿:我自豪我是一名幼师
2014/09/10 职场文书
收款授权委托书
2014/10/02 职场文书
员工工作表扬信
2015/05/05 职场文书
春晚观后感
2015/06/11 职场文书