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 相关文章推荐
JS创建优美的页面滑动块效果 - Glider.js
Sep 27 Javascript
Extjs学习笔记之五 一个小细节renderTo和applyTo的区别
Jan 07 Javascript
javascript学习笔记(一) 在html中使用javascript
Jun 18 Javascript
JavaScript使用concat连接数组的方法
Apr 06 Javascript
Eclipse引入jquery报错如何解决
Dec 01 Javascript
基于JavaScript实现根据手机定位获取当前具体位置(X省X市X县X街道X号)
Dec 29 Javascript
vue分类筛选filter方法简单实例
Mar 30 Javascript
Bootstrap模态对话框中显示动态内容的方法
Aug 10 Javascript
angular5 子组件监听父组件传入值的变化方法
Sep 30 Javascript
vue 动态表单开发方法案例详解
Dec 02 Javascript
koa-passport实现本地验证的方法示例
Feb 20 Javascript
JQuery通过键盘控制键盘按下与松开触发事件
Aug 07 jQuery
关于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
世界上第一台立体声收音机
2021/03/01 无线电
Blitz templates 最快的PHP模板引擎
2010/04/06 PHP
PHP生成图片验证码、点击切换实例
2014/06/25 PHP
JavaScript的9个陷阱及评点分析
2008/05/16 Javascript
PPK 谈 JavaScript 的 this 关键字 [翻译]
2009/09/29 Javascript
javascript获取作用在元素上面的样式属性代码
2012/09/20 Javascript
使用jquery实现div的tab切换实例代码
2013/05/27 Javascript
JS+css 图片自动缩放自适应大小
2013/08/08 Javascript
jQuery中[attribute*=value]选择器用法实例
2014/12/31 Javascript
RequireJS入门一之实现第一个例子
2015/09/30 Javascript
微信小程序 定义全局数据、函数复用、模版等详细介绍
2016/10/27 Javascript
获取select的value、text值的简单示例(jquery与javascript)
2016/12/07 Javascript
vue2.0实现导航菜单切换效果
2017/05/08 Javascript
React-Native之定时器Timer的实现代码
2017/10/04 Javascript
Vue父子模版传值及组件传值的三种方法
2017/11/27 Javascript
React性能优化系列之减少props改变的实现方法
2019/01/17 Javascript
vue自定义js图片碎片轮播图切换效果的实现代码
2019/04/28 Javascript
微信公众号平台接口开发 菜单管理的实现
2019/08/14 Javascript
vue集成一个支持图片缩放拖拽的富文本编辑器
2021/01/29 Vue.js
[02:39]DOTA2英雄基础教程 天怒法师
2013/11/29 DOTA
python的几种开发工具介绍
2007/03/07 Python
Python3写入文件常用方法实例分析
2015/05/22 Python
Python使用正则表达式实现文本替换的方法
2017/04/18 Python
浅谈Python中重载isinstance继承关系的问题
2018/05/04 Python
python3 requests中使用ip代理池随机生成ip的实例
2018/05/07 Python
django框架自定义模板标签(template tag)操作示例
2019/06/24 Python
python GUI库图形界面开发之PyQt5 MDI(多文档窗口)QMidArea详细使用方法与实例
2020/03/05 Python
pycharm设置python文件模板信息过程图解
2020/03/10 Python
python获取响应某个字段值的3种实现方法
2020/04/30 Python
澳大利亚玩具剧场:Toy Playhouse
2019/03/03 全球购物
金鑫耀Java笔试题
2014/09/06 面试题
毕业生幼师求职自荐信
2013/10/01 职场文书
珠宝的促销活动方案
2014/08/31 职场文书
防暑降温通知书
2015/04/27 职场文书
运动会广播稿50字
2015/08/19 职场文书
springboot 全局异常处理和统一响应对象的处理方式
2022/06/28 Java/Android