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 八进制转义字符(8进制)
Apr 08 Javascript
javascript上传图片前预览图片兼容大多数浏览器
Oct 25 Javascript
javascript 终止函数执行操作
Feb 14 Javascript
javascript中innerText和innerHTML属性用法实例分析
May 13 Javascript
Jquery使用css方法改变样式实例
May 18 Javascript
基于jQuey实现鼠标滑过变色(整行变色)
Dec 07 Javascript
第一章之初识Bootstrap
Apr 25 Javascript
vue高德地图之玩转周边
Jun 16 Javascript
详解tween.js的使用教程
Sep 14 Javascript
基于VUE实现的九宫格抽奖功能
Sep 30 Javascript
JavaScript数据结构之栈实例用法
Jan 18 Javascript
JavaScript中的this原理及6种常见使用场景详解
Feb 14 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开发的一些注意点总结
2010/10/12 PHP
PHP代码判断设备是手机还是平板电脑(两种方法)
2015/10/19 PHP
JavaScript中的运算符种类及其规则介绍
2013/09/26 Javascript
控制文字内容的显示与隐藏示例
2014/06/11 Javascript
js读取cookie方法总结
2014/10/31 Javascript
ECMAScript5(ES5)中bind方法使用小结
2015/05/07 Javascript
web 屏蔽BackSpace键实例代码
2016/12/24 Javascript
jquery仿ps颜色拾取功能
2017/03/08 Javascript
AugularJS从入门到实践(必看篇)
2017/07/10 Javascript
JS+HTML5 FileReader实现文件上传前本地预览功能
2020/03/27 Javascript
微信小程序页面缩放式侧滑效果的实现代码
2018/11/15 Javascript
Element实现表格分页数据选择+全选所有完善批量操作
2019/06/07 Javascript
微信小程序移动拖拽视图-movable-view实例详解
2019/08/17 Javascript
[02:39]DOTA2英雄基础教程 天怒法师
2013/11/29 DOTA
python client使用http post 到server端的代码
2013/02/10 Python
为Python程序添加图形化界面的教程
2015/04/29 Python
Python for Informatics 第11章 正则表达式(一)
2016/04/21 Python
Python数据结构与算法之图的最短路径(Dijkstra算法)完整实例
2017/12/12 Python
Python基于Tkinter模块实现的弹球小游戏
2018/12/27 Python
使用python turtle画高达
2020/01/19 Python
django有外键关系的两张表如何相互查找
2020/02/10 Python
Ubuntu20下的Django安装的方法步骤
2021/01/24 Python
css3 clip实现圆环进度条的示例代码
2018/02/07 HTML / CSS
美国瑜伽服装和装备购物网站:Mukha Yoga
2019/02/22 全球购物
数控机械专业个人的自我评价
2014/01/02 职场文书
企业形象策划方案
2014/05/29 职场文书
2015年党性分析材料
2014/12/19 职场文书
2015年基层党组织公开承诺书
2015/01/21 职场文书
2015年乡镇发展党员工作总结
2015/03/31 职场文书
上市公司财务总监岗位职责
2015/04/03 职场文书
2015年纪检监察工作总结
2015/04/08 职场文书
首次购房证明
2015/06/19 职场文书
2016幼儿园新学期寄语
2015/12/03 职场文书
2019年教师入党申请书
2019/06/27 职场文书
python实现简单的聊天小程序
2021/07/07 Python
Spring Data JPA框架持久化存储数据到数据库
2022/04/28 Java/Android