懒加载即按需加载 ,<img>
的 src 默认为一张 loading 小图片,实际图片地址在自定义属性
记录(如:data-src)。当图片出现在 viewport 时,才进行加载把实际地址设置到src。加载成功时除去自定义属性
。
<img class="list-img" src="loading.gif" data-src="actual.jpg" />
实际图片显示的时机
遍历所有这些特定的图片,当图片的顶部 offsetTop < 整个可视高度 clientHeight + 整个滚动条高度 scrollTop 时,就认为图片出现在可视区域。这时把图片的 src 替换为实际地址,还可以加入节流 throttle
实现例子
;(function(win, doc){
var oImgList = doc.getElementsByClassName('J_imgList')[0],
data = JSON.parse(doc.getElementById('J_data').innerHTML),
imgTpl = doc.getElement('J_imgTpl').innerHTML, //显示模版
/*
<img src="img/loading.gif" data-src="{{img}}" name="{{name}}" />
*/
oImg = doc.getElementsByClassName('list-img');
var init = function(){
renderList(data);
bindEvent();
setTimeout(function(){ //首次进入滚动最顶
window.scrollTo(0,0);
}, 150)
}
function bindEvent(){
window.onload = window.onscroll = throttle(imgLazyLoad(oImg), 300);
}
function renderList(data){
var list = '';
data.forEach(function(elem){
list += imgTpl.replace(/\{\{(.*?)\}\}/g, function(node, key){
return {
img: elem.img,
name: elem.name,
}[key];
});
});
return list;
}
init();
})(window, document);
function imgLazyLoad(images){
var imgLen = images.length,
n = 0; //加载记录
return function(){
var cHeight = document.documentElement.clientHeight,
sTop = document.documentElement.scrollTop || document.body.scrollTop,
imgItem;
for(var i=n; i<imgLen; i++){ //加载过后不再加载
imgItem = image[i];
if(imgItem.offsetTop < cHeight + sTop){
imgItem.src = imgItem.getAttribute('data-src');
imgItem.removeAttribute('data-src');
n++;
}
}
}
}
原生支持
对于一些较新的浏览器,img 标签的 loading 属性是原生支持懒加载:
IE | Edege | FireFox | Chrome | Safari | IOS Safari | Android Browser | Chrome for Android | FireFox for Android |
---|---|---|---|---|---|---|---|---|
No | 89 | 75 | 77 | No | No | 89 | 89 | 86 |
- eager:无论图片是否在可视区域,都会直接加载图片。
- lazy:推迟图片的加载,当图片滚动到距离可视区域一定阈值(视浏览器的实现而定)的时候,再加载图片。
- auto:由浏览器自行决定
注意
不要给首屏出现在可视区域的图片设置懒加载,因为它本身就在可视区域,应该尽快加载,以让用户尽早看到图片。
另外,使用懒加载的图片应该尽量设置宽高,这样可以避免抖动:在等图片加载的时候,相应区域会显示为空白,其他元素不会占位。如果不设置宽高,其它元素就有可能会占位,图片加载完成之后,又会把占位的元素挤下去,造成抖动。