懒加载技术(简称lazyload)并非新技术,它是js程序员对网页性能优化的一种方案。lazyload的核心是按需加载。在大型网站中都有lazyload的身影,例如谷歌的图片搜索页,迅雷首页,淘宝网,QQ空间等。所以掌握lazyload技术是个不错的选择,惋惜jquery插件lazy load官网(http://www.appelsiini.net/projects/lazyload)称不支持新版浏览器。jquery
lazyload在什么场合中应用比较合适?
涉及到图片,falsh资源,iframe,网页编辑器(相似FCK)等占用较大带宽,且这些模块暂且不在浏览器可视区内,所以可使用lazyload在适当的时候加载该类资源。避免网页打开时加载过多资源,让用户等待过久。程序员
如何实现lazyload?
lazyload的难点在如何在适当的时候加载用户须要的资源(这里用户须要的资源指该资源呈如今浏览器可视区域)。所以咱们须要知道几点信息来肯定目标是否已呈如今客户区,其中包括:数组
- 可视区域相对于浏览器顶端位置;
- 待加载资源相对于浏览器顶端位置。
在获得以上两点数据后,经过以下函数,即可得出某对象是否在浏览器可视区域了。
返回浏览器的可视区域位置
浏览器
代码以下:
// 返回浏览器的可视区域位置
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()返回目标模块区域信息。此时肯定目标模块是否出如今客户区其实是肯定如上两个矩形是否相交。
app
代码以下:
// 判断两个矩形是否相交,返回一个布尔值
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事件中编写一些代码监控目标区域是否呈如今客户区。
jquery插件
代码以下:
<div ></div>
<div id="div1" >
</div>
代码以下:
var div1 = document.getElementById("div1");
window.onscroll = function(){
var prec1 = getClient();
var prec2 = getSubClient(div1);
if (intens(prec1, prec2)) {
alert("true");
}
};
咱们只须要在弹出窗口的地方加载咱们须要的资源。
这里值得注意的是 : 目标对象呈如今客户区域时,会随着滚动而不断的弹出窗口。所以咱们须要在弹出第一个窗口后取消对该区域的监测,这里用一个数组来收集须要监测的对象,同时将监测的逻辑抽出来。同时须要注意 onscroll事件和onresize事件都会改变游览器可视区域信息,所以在该类事件触发后须要从新计算,这里用autocheck()函数实现。
增长元素 :编辑器
代码以下:函数
<div id="div2" >
代码以下:
// 比较某个子区域是否呈如今浏览器区域
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("div1");
// 子区域二
var d2 = document.getElementById("div2");
// 须要按需加载区域集合
var arr = [d1, d2];
window.onscroll = function(){
// 从新计算
autocheck();
}
window.onresize = function(){
// 从新计算
autocheck(); }