huyueshan

导航

图片懒加载 echo.js

  1 (function (root, factory) {
  2   if (typeof define === 'function' && define.amd) {
  3     define(function() {
  4       return factory(root);
  5     });
  6   } else if (typeof exports === 'object') {
  7     module.exports = factory;
  8   } else {
  9     root.echo = factory(root);
 10   }
 11 })(this, function (root) {
 12 
 13   'use strict';
 14 
 15   var echo = {};
 16 
 17   var callback = function () {};
 18 
 19   var offset, poll, delay, useDebounce, unload;
 20 
 21   var isHidden = function (element) {
 22     return (element.offsetParent === null);
 23   };
 24   
 25   var inView = function (element, view) {
 26     if (isHidden(element)) {
 27       return false;
 28     }
 29 
 30     var box = element.getBoundingClientRect();
 31     return (box.right >= view.l && box.bottom >= view.t && box.left <= view.r && box.top <= view.b);
 32   };
 33 
 34   var debounceOrThrottle = function () {
 35     if(!useDebounce && !!poll) {
 36       return;
 37     }
 38     clearTimeout(poll);
 39     poll = setTimeout(function(){
 40       echo.render();
 41       poll = null;
 42     }, delay);
 43   };
 44 
 45   echo.init = function (opts) {
 46     opts = opts || {};
 47     var offsetAll = opts.offset || 0;
 48     var offsetVertical = opts.offsetVertical || offsetAll;
 49     var offsetHorizontal = opts.offsetHorizontal || offsetAll;
 50     var optionToInt = function (opt, fallback) {
 51       return parseInt(opt || fallback, 10);
 52     };
 53     offset = {
 54       t: optionToInt(opts.offsetTop, offsetVertical),
 55       b: optionToInt(opts.offsetBottom, offsetVertical),
 56       l: optionToInt(opts.offsetLeft, offsetHorizontal),
 57       r: optionToInt(opts.offsetRight, offsetHorizontal)
 58     };
 59     delay = optionToInt(opts.throttle, 250);
 60     useDebounce = opts.debounce !== false;
 61     unload = !!opts.unload;
 62     callback = opts.callback || callback;
 63     echo.render();
 64     if (document.addEventListener) {
 65       root.addEventListener('scroll', debounceOrThrottle, false);
 66       root.addEventListener('load', debounceOrThrottle, false);
 67     } else {
 68       root.attachEvent('onscroll', debounceOrThrottle);
 69       root.attachEvent('onload', debounceOrThrottle);
 70     }
 71   };
 72 
 73   echo.render = function () {
 74     var nodes = document.querySelectorAll('img[data-echo], [data-echo-background]');
 75     var length = nodes.length;
 76     var src, elem;
 77     var view = {
 78       l: 0 - offset.l,
 79       t: 0 - offset.t,
 80       b: (root.innerHeight || document.documentElement.clientHeight) + offset.b,
 81       r: (root.innerWidth || document.documentElement.clientWidth) + offset.r
 82     };
 83     for (var i = 0; i < length; i++) {
 84       elem = nodes[i];
 85       if (inView(elem, view)) {
 86 
 87         if (unload) {
 88           elem.setAttribute('data-echo-placeholder', elem.src);
 89         }
 90 
 91         if (elem.getAttribute('data-echo-background') !== null) {
 92           elem.style.backgroundImage = "url(" + elem.getAttribute('data-echo-background') + ")";
 93         }
 94         else {
 95           elem.src = elem.getAttribute('data-echo');
 96         }
 97 
 98         if (!unload) {
 99           elem.removeAttribute('data-echo');
100           elem.removeAttribute('data-echo-background');
101         }
102 
103         callback(elem, 'load');
104       }
105       else if (unload && !!(src = elem.getAttribute('data-echo-placeholder'))) {
106 
107         if (elem.getAttribute('data-echo-background') !== null) {
108           elem.style.backgroundImage = "url(" + src + ")";
109         }
110         else {
111           elem.src = src;
112         }
113 
114         elem.removeAttribute('data-echo-placeholder');
115         callback(elem, 'unload');
116       }
117     }
118     if (!length) {
119       echo.detach();
120     }
121   };
122 
123   echo.detach = function () {
124     if (document.removeEventListener) {
125       root.removeEventListener('scroll', debounceOrThrottle);
126     } else {
127       root.detachEvent('onscroll', debounceOrThrottle);
128     }
129     clearTimeout(poll);
130   };
131 
132   return echo;
133 
134 });

如何使用

1、引入文件

  1. <script src="js/echo.min.js"></script>  

2、HTML结构

  1. <img src="img/blank.gif" alt="Photo" data-echo="img/photo.jpg" />  

blank.gif 是一个 1 x 1 的图片,用做默认图片,data-echo 的属性值是图片的真实地址。你可以给图片设置宽度和高度,或者在 CSS 中设置,否则似乎很底部很底部的图片才会延迟加载。

3、JavaScript

1     echo.init({  
2     offset: 100,  
3     throttle: 250,  
4     unload: false,  
5     callback: function (element, op) {  
6     console.log('loaded ok.');  
7     }  
8     });  

4、常用参数及方法说明

参数 描述 默认值
offset 离可视区域多少像素的图片可以被加载 0
throttle 图片延迟多少毫秒加载 250
debounce 防抖动 true
unload 告诉echo是加载还是卸载视图中的图片,当图片离开视图区域时触发 false
callback 回调函数,用来检测图片是否加载 function()

最后echo.js还提供了一个.render()方法,用法如下:

echo.render();  

应用场景:当你的页面没有发生滚动,而你想加载即将要显示的图片,如图片轮播,当第一张图片显示完,接着滑动展示第二张图片,这个时候使用echo.render()

 

提前加载第二张图片,就不会出现图片加载卡顿白屏等现象。

posted on 2019-03-10 19:55  huyueshan  阅读(442)  评论(0编辑  收藏  举报