如何使用echo.js實現圖片的懶加載(整理)
一、總結
一句話總結:a、在img標簽中添加data-echo屬性加載真實圖片:<img class="loading" src="blank.gif" data-echo="圖片真實路徑" />,在src屬性中加載loading的那個圖片; b、引入echo.js; c、在js代碼中初始化echo.js(和別的js的用法一樣)
?
1、echo.js中是如何判斷元素距離出現在視野里的長度還有多少?
判斷距離圖片的高啊,element.getBoundingClientRect(),就能得到元素相對于視窗的四個距離
?
2、已經有了是否加載的判斷函數,那么如何做到圖片的懶加載?
先加載loadding小菊花圖片,當滿足懶加載的條件時候,切換img的src屬性,
對于img元素的設置有兩個比較重要的值一個是src,一個是data-echo ,(還有一個是背景圖片,不太重要,忽略他)兩個,src設置小菊花的地址,data-echo真實的地址;
?
3、echo.js的優點是什么?
Echo 是一個獨立的 JavaScript 懶加載圖像的工具,快速、體積小(不足1k)和使用 HTML5 的 data- 屬性。Echo 支持 IE8+ 。
?
?
二、使用echo.js實現圖片懶加載
參考:使用echo.js實現圖片懶加載 - CSDN博客
https://blog.csdn.net/u010394015/article/details/52385791
?
<!DOCTYPE html>
<html><head><meta charset="UTF-8"><title></title><style>* {margin: 0;padding: 0;font-family: "微軟雅黑";}ul li img {width: 300px;display: block;background: url('pic/bg.png') no-repeat center #ccc;}</style></head><body><ul><li><img src="pic/blank.gif" data-echo="img/aaa.jpg" /></li><li><img src="pic/blank.gif" data-echo="img/aaa.jpg" /></li><li><img src="pic/blank.gif" data-echo="img/aaa.jpg" /></li><li><img src="pic/blank.gif" data-echo="img/aaa.jpg" /></li><li><img src="pic/blank.gif" data-echo="img/aaa.jpg" /></li><li><img src="pic/blank.gif" data-echo="img/aaa.jpg" /></li><li><img src="pic/blank.gif" data-echo="img/aaa.jpg" /></li><li><img src="pic/blank.gif" data-echo="img/aaa.jpg" /></li><li><img src="pic/blank.gif" data-echo="img/aaa.jpg" /></li><li><img src="pic/blank.gif" data-echo="img/aaa.jpg" /></li><li><img src="pic/blank.gif" data-echo="img/aaa.jpg" /></li><li><img src="pic/blank.gif" data-echo="img/aaa.jpg" /></li><li><img src="pic/blank.gif" data-echo="img/aaa.jpg" /></li><li><img src="pic/blank.gif" data-echo="img/aaa.jpg" /></li><li><img src="pic/blank.gif" data-echo="img/aaa.jpg" /></li><li><img src="pic/blank.gif" data-echo="img/aaa.jpg" /></li><li><img src="pic/blank.gif" data-echo="img/aaa.jpg" /></li><li><img src="pic/blank.gif" data-echo="img/aaa.jpg" /></li><li><img src="pic/blank.gif" data-echo="img/aaa.jpg" /></li><li><img src="pic/blank.gif" data-echo="img/aaa.jpg" /></li><li><img src="pic/blank.gif" data-echo="img/aaa.jpg" /></li></ul><script src="js/echo.js"></script><script>echo.init();</script></body></html>
echo.js代碼
?
?
/*! echo.js v1.6.0 | (c) 2014 @toddmotto | https://github.com/toddmotto/echo */ ! function(t, e) {"function" == typeof define && define.amd ? define(function() {return e(t)}) : "object" == typeof exports ? module.exports = e : t.echo = e(t)
}(this, function(t) {"use strict";var e, n, o, r, c, a = {},d = function() {},u = function(t, e) {var n = t.getBoundingClientRect();return n.right >= e.l && n.bottom >= e.t && n.left <= e.r && n.top <= e.b},l = function() {(r || !n) && (clearTimeout(n), n = setTimeout(function() {a.render(), n = null}, o))};return a.init = function(n) {n = n || {};var u = n.offset || 0,i = n.offsetVertical || u,f = n.offsetHorizontal || u,s = function(t, e) {return parseInt(t || e, 10)};e = {t: s(n.offsetTop, i),b: s(n.offsetBottom, i),l: s(n.offsetLeft, f),r: s(n.offsetRight, f)}, o = s(n.throttle, 250), r = n.debounce !== !1, c = !!n.unload, d = n.callback || d, a.render(), document.addEventListener ? (t.addEventListener("scroll", l, !1), t.addEventListener("load", l, !1)) : (t.attachEvent("onscroll", l), t.attachEvent("onload", l))}, a.render = function() {for (var n, o, r = document.querySelectorAll("img[data-echo], [data-echo-background]"), l = r.length, i = {l: 0 - e.l,t: 0 - e.t,b: (t.innerHeight || document.documentElement.clientHeight) + e.b,r: (t.innerWidth || document.documentElement.clientWidth) + e.r}, f = 0; l > f; f++) o = r[f], u(o, i) ? (c && o.setAttribute("data-echo-placeholder", o.src), null !== o.getAttribute("data-echo-background") ? o.style.backgroundImage = "url(" + o.getAttribute("data-echo-background") + ")" : o.src = o.getAttribute("data-echo"), c || o.removeAttribute("data-echo"), d(o, "load")) : c && (n = o.getAttribute("data-echo-placeholder")) && (null !== o.getAttribute("data-echo-background") ? o.style.backgroundImage = "url(" + n + ")" : o.src = n, o.removeAttribute("data-echo-placeholder"), d(o, "unload"));l || a.detach()}, a.detach = function() {document.removeEventListener ? t.removeEventListener("scroll", l) : t.detachEvent("onscroll", l), clearTimeout(n)}, a
});
三、圖片懶加載庫echo.js源碼學習
參考:圖片懶加載庫echo.js源碼學習 - CSDN博客https://blog.csdn.net/a54654132/article/details/77427507
最近不是在學習設計模式嗎,然后就看到了代理模式加載圖片的樣例,然后自己實現了一下,就發現,自己寫的這貨每次就只能加載一張圖片,而且圖片要放在哪也是個很嚴重的問題
然后就去了 gayhub 找了找了找流行的圖片懶加載庫,這一找,就找到了一個echo.j是,打開一看,源碼只有100多行吧,震驚。。,看完源碼,哎,木有上代理模式呀
仔細學習了下源碼:覺得這種做法比較適合圖片位置確定場景的吧,比如文章啊,一篇文章老長了,里面有蠻多圖片散落在不同的地方,這樣就比較合適,有可能有很多圖片讀者都不會翻到哪里,加載下來就浪費了
關鍵點:
1.如何判斷元素距離出現在視野里的長度還有多少?以常見鼠標往下滾動,圖片在下面為例
靈魂畫手哈哈,,,;H1是視窗的高度,window.innerHeight可以獲得,H2就是提供給使用者設置的offsetBottom
然后祭出一個大招!element.getBoundingClientRect(),就能得到元素相對于視窗的四個距離
var H=Element.getboundingclientrect().top;
var flag=H-(H1+H2);//當flag值小于0就代表可以開始加載圖片了
那么,看看源碼里面是怎么寫的:
var offset = {//四個值由用戶傳入決定,默認為0t: ,b:,l: ,r:
};
var view = { //計算鄰界的距離l: 0 - offset.l,t: 0 - offset.t,b: (root.innerHeight || document.documentElement.clientHeight) + offset.b,r: (root.innerWidth || document.documentElement.clientWidth) + offset.r
};var isHidden = function (element) {return (element.offsetParent === null); //element.offsetParent 表示父元素,如果為null證明沒有在添加到DOM里面,或者position值為fixed};var inView = function (element, view) { //判斷是否在視圖中調用這個函數判斷if (isHidden(element)) { //判斷是否在界面上return false;}var box = element.getBoundingClientRect(); //計算四邊的距離是否滿足條件return (box.right >= view.l && box.bottom >= view.t && box.left <= view.r && box.top <= view.b);};
2.已經有了是否加載的判斷函數,那么如何做到圖片的懶加載?
先加載loadding小菊花圖片,當滿足懶加載的條件時候,切換img的src屬性,
對于img元素的設置有兩個比較重要的值一個是src,一個是data-echo ,(還有一個是背景圖片,不太重要,忽略他)兩個,src設置小菊花的地址,data-echo真實的地址;
那么所有頁面元素都這樣設置后,會有什么影響?
當所有圖片都用設置src為同一值,也就是用同一張菊花圖,加載完之后就可以通用了
img這個元素的特性就是,當設置了src屬性,他會去先加載這張圖圖片,如果在js里面馬上改變了img的src屬性,他會同事再進行一次網絡請求去加載你js設置的src地址的圖片
但是 會先將html里面設置的src圖片加載完,顯示,你什么時候加載完第二個圖片什么時候替換,如果你在第二張圖片加載的時候又改變了src的值,,,那也是一樣的,什么加載完什么時候顯示,沒加載完的情況下顯示原來的
源代碼:
if (inView(elem, view)) {//是否滿足加載條件if (unload) {//如果設置超出了不加載,保存小菊花地址在data-echo-placeholder屬性elem.setAttribute('data-echo-placeholder', elem.src);}if (elem.getAttribute('data-echo-background') !== null) {//img的背景圖片elem.style.backgroundImage = 'url(' + elem.getAttribute('data-echo-
background') + ')';}//當ele的src不等于data-echo的值,也就是真蒸的圖片地址,改變圖片的srcelse if (elem.src !== (src = elem.getAttribute('data-echo'))) {elem.src = src;}if (!unload) { //如果沒有設置超出不加載,在這里就可以清除這些屬性了elem.removeAttribute('data-echo');elem.removeAttribute('data-echo-background');}callback(elem, 'load');}else if (unload && !!(src = elem.getAttribute('data-echo-placeholder'))) {//處理超出不加載圖片的情況,把原來保存的小菊花圖賦給elem的src//因為小菊花是最開始就加載好了的,所以圖片切換回小菊花,不再加載之前設置的真實圖片if (elem.getAttribute('data-echo-background') !== null) {elem.style.backgroundImage = 'url(' + src + ')';}else {elem.src = src;}elem.removeAttribute('data-echo-placeholder'); callback(elem, 'unload');}}if (!length) {echo.detach();//移除事件監聽}
3,scroll函數節流
函數節流,兩種方式:
1:在滾動的時候不會觸發,滾動停下來才會隔一段時間觸發
2:每隔一段事件都觸發
//第一種方式,每次滾動過程中一直觸發,每次都會新清除上一次的setTimout,添加一個新的setTimout
var poll;
function throttle(){ clearTimeout(poll);poll=setTimeout(function(){echo.render();},delay||250)
}
var poll;
function throttle(){
if(poll){ //存在setTimout,不清除,直接返回return ;
}
clearTimout(poll);
poll=setTimeout(function(){echo.render();poll=null; //允許再次添加定時器
},delay||250)
}
?
四、WEB前端 實現圖片懶加載 echo.js
參考:WEB前端 實現圖片懶加載 echo.js - CSDN博客https://blog.csdn.net/weixin_38984353/article/details/80340795
echo.js是一個輕小的圖片懶加載js插件,在使用過程中很多朋友可能是直接自定義一張占位圖片,可能會造成圖片的變形等。其實這并不是最佳的解決方案。下面給大家介紹另一種方法,簡單的控制下css,實現loading效果
首先我們準備一張1*1px透明gif圖片(blank.gif),和一個loading圖片。
<img class="loading" src="blank.gif" data-echo="圖片真實路徑" />
- 1
Echo 是一個獨立的 JavaScript 懶加載圖像的工具,快速、體積小(不足1k)和使用 HTML5 的 data- 屬性。Echo 支持 IE8+ 。
示例代碼
<body>
<img src="img/blank.gif" alt="Photo" data-echo="img/photo.jpg">
//blank.gif為預加載的照片,photo.jpg為最后顯示的照片<script src="dist/echo.js"></script> <script> Echo.init({ offset: 0, throttle: 250 //設置圖片延遲加載的時間 }); // Echo.render(); is also available for non-scroll callbacks </script>
</body>
?
?
?