圖片懶載入庫echo.js源碼學習

來源:互聯網
上載者:User

標籤:屬性   一個   顯示   多行   計算   設定   ret   一段   logs   

最近不是在學習設計模式嗎,然後就看到了代理模式載入圖片的範例,然後自己實現了一下,就發現,自己寫的這貨每次就只能載入一張圖片,而且圖片要放在哪也是個很嚴重的問題

然後就去了 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 = {//四個值由使用者傳入決定,預設為0      t: ,      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的值,也就是真蒸的圖片地址,改變圖片的src        else 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,添加一個新的setTimoutvar 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)}

  

 

圖片懶載入庫echo.js源碼學習

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.