懒加载即按需加载 ,<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:由浏览器自行决定
注意
不要给首屏出现在可视区域的图片设置懒加载,因为它本身就在可视区域,应该尽快加载,以让用户尽早看到图片。
另外,使用懒加载的图片应该尽量设置宽高,这样可以避免抖动:在等图片加载的时候,相应区域会显示为空白,其他元素不会占位。如果不设置宽高,其它元素就有可能会占位,图片加载完成之后,又会把占位的元素挤下去,造成抖动。
