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之Document元素选择器篇
Aug 14 Javascript
JS获取月的最后一天与JS得到一个月份最大天数的实例代码
Dec 16 Javascript
javascript的几种继承方法介绍
Mar 22 Javascript
JS封装的三级联动菜单(使用时只需要一行js代码)
Oct 24 Javascript
使用vue.js编写蓝色拼图小游戏
Mar 17 Javascript
jQuery选择器特殊字符与属性空格问题
Aug 14 jQuery
JS实现的JSON序列化操作简单示例
Jul 02 Javascript
微信小程序有旋转动画效果的音乐组件实例代码
Aug 22 Javascript
JavaScript时间日期操作实例小结【5个示例】
Dec 22 Javascript
eslint 的三大通用规则详解
May 16 Javascript
对vuex中getters计算过滤操作详解
Nov 06 Javascript
webpack3.0升级4.0的方法步骤
Apr 02 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
2006/12/14 PHP
简单谈谈php中的unicode和utf8编码
2015/06/10 PHP
php实现购物车功能(以大苹果购物网为例)
2017/03/09 PHP
PHP单例模式数据库连接类与页面静态化实现方法
2019/03/20 PHP
比较详细的关于javascript中void(0)的具体含义解释
2007/08/02 Javascript
初学JavaScript_03(ExtJs Grid的简单使用)
2008/10/02 Javascript
js function使用心得
2010/05/10 Javascript
js 实现css风格选择器(压缩后2KB)
2012/01/12 Javascript
用jQuery toggleClass 实现鼠标移上变色
2014/05/14 Javascript
jQuery取id有.的值的方法
2014/05/21 Javascript
js常用数组操作方法简明总结
2014/06/20 Javascript
jQuery实现单击和鼠标感应事件
2015/02/01 Javascript
js判断手机号运营商的方法
2015/10/23 Javascript
概述BootStrap中role=&quot;form&quot;及role作用角色
2016/12/08 Javascript
vue+ElementUI实现订单页动态添加产品数据效果实例代码
2017/07/13 Javascript
AngularJs导出数据到Excel的示例代码
2017/08/11 Javascript
vue实现商城购物车功能
2017/11/27 Javascript
vue、react等单页面项目应该这样子部署到服务器
2018/01/03 Javascript
webstorm中vue语法的支持详解
2018/05/09 Javascript
通过jquery.cookie.js实现记住用户名、密码登录功能
2018/06/20 jQuery
Vue中使用create-keyframe-animation与动画钩子完成复杂动画
2019/04/09 Javascript
js实现前端界面导航栏下拉列表
2020/08/27 Javascript
[01:20]DOTA2 2017国际邀请赛冠军之路无止竞
2017/06/19 DOTA
[01:11:28]DOTA2-DPC中国联赛定级赛 RNG vs Phoenix BO3第一场 1月8日
2021/03/11 DOTA
tensorflow实现对图片的读取的示例代码
2018/02/12 Python
钉钉群自定义机器人消息Python封装的实例
2019/02/20 Python
利用jupyter网页版本进行python函数查询方式
2020/04/14 Python
德国购买健身器材:AsVIVA
2017/08/09 全球购物
大学生四个方面的自我评价
2013/09/19 职场文书
国贸专业大学生职业生涯规划范文
2014/01/10 职场文书
院领导写的就业推荐信
2014/03/09 职场文书
房产继承公证书
2014/04/09 职场文书
请假条的格式
2014/04/11 职场文书
青春励志演讲稿
2014/04/29 职场文书
2021年国漫热度排行前十,完美世界上榜,第四是美国动画作品
2022/03/18 国漫
SQL Server中搜索特定的对象
2022/05/25 SQL Server