懒加载即按需加载 ,<img> 的 src 默认为一张 loading 小图片,实际图片地址在自定义属性记录(如:data-src)。当图片出现在 viewport 时,才进行加载把实际地址设置到src。加载成功时除去自定义属性

  1. <img class="list-img" src="loading.gif" data-src="actual.jpg" />

实际图片显示的时机

遍历所有这些特定的图片,当图片的顶部 offsetTop < 整个可视高度 clientHeight + 整个滚动条高度 scrollTop 时,就认为图片出现在可视区域。这时把图片的 src 替换为实际地址,还可以加入节流 throttle

函数节流 throttle

实现例子

  1. ;(function(win, doc){
  2. var oImgList = doc.getElementsByClassName('J_imgList')[0],
  3. data = JSON.parse(doc.getElementById('J_data').innerHTML),
  4. imgTpl = doc.getElement('J_imgTpl').innerHTML, //显示模版
  5. /*
  6. <img src="img/loading.gif" data-src="{{img}}" name="{{name}}" />
  7. */
  8. oImg = doc.getElementsByClassName('list-img');
  9. var init = function(){
  10. renderList(data);
  11. bindEvent();
  12. setTimeout(function(){ //首次进入滚动最顶
  13. window.scrollTo(0,0);
  14. }, 150)
  15. }
  16. function bindEvent(){
  17. window.onload = window.onscroll = throttle(imgLazyLoad(oImg), 300);
  18. }
  19. function renderList(data){
  20. var list = '';
  21. data.forEach(function(elem){
  22. list += imgTpl.replace(/\{\{(.*?)\}\}/g, function(node, key){
  23. return {
  24. img: elem.img,
  25. name: elem.name,
  26. }[key];
  27. });
  28. });
  29. return list;
  30. }
  31. init();
  32. })(window, document);
  33. function imgLazyLoad(images){
  34. var imgLen = images.length,
  35. n = 0; //加载记录
  36. return function(){
  37. var cHeight = document.documentElement.clientHeight,
  38. sTop = document.documentElement.scrollTop || document.body.scrollTop,
  39. imgItem;
  40. for(var i=n; i<imgLen; i++){ //加载过后不再加载
  41. imgItem = image[i];
  42. if(imgItem.offsetTop < cHeight + sTop){
  43. imgItem.src = imgItem.getAttribute('data-src');
  44. imgItem.removeAttribute('data-src');
  45. n++;
  46. }
  47. }
  48. }
  49. }

原生支持

对于一些较新的浏览器,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:由浏览器自行决定

注意

不要给首屏出现在可视区域的图片设置懒加载,因为它本身就在可视区域,应该尽快加载,以让用户尽早看到图片。
另外,使用懒加载的图片应该尽量设置宽高,这样可以避免抖动:在等图片加载的时候,相应区域会显示为空白,其他元素不会占位。如果不设置宽高,其它元素就有可能会占位,图片加载完成之后,又会把占位的元素挤下去,造成抖动。