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 });
一、引入文件node
二、HTML結構函數
blank.gif 是一個 1 x 1 的圖片,用作默認圖片,data-echo 的屬性值是圖片的真實地址。你能夠給圖片設置寬度和高度,或者在 CSS 中設置,不然彷佛很底部很底部的圖片纔會延遲加載。this
三、JavaScripturl
1 echo.init({ 2 offset: 100, 3 throttle: 250, 4 unload: false, 5 callback: function (element, op) { 6 console.log('loaded ok.'); 7 } 8 });
四、經常使用參數及方法說明spa
參數 | 描述 | 默認值 |
offset | 離可視區域多少像素的圖片能夠被加載 | 0 |
throttle | 圖片延遲多少毫秒加載 | 250 |
debounce | 防抖動 | true |
unload | 告訴echo是加載仍是卸載視圖中的圖片,當圖片離開視圖區域時觸發 | false |
callback | 回調函數,用來檢測圖片是否加載 | function() |
最後echo.js還提供了一個.render()方法,用法以下:code
echo.render(); blog
應用場景:當你的頁面沒有發生滾動,而你想加載即將要顯示的圖片,如圖片輪播,當第一張圖片顯示完,接着滑動展現第二張圖片,這個時候使用echo.render()圖片
提早加載第二張圖片,就不會出現圖片加載卡頓白屏等現象。ip