原生實現img-lazyLoad:圖片延遲加載(基於intersection Observer)

點擊查看視頻教程哦!!!!

intersection Observer簡介

點擊查閱MDN關於此api的使用說明css

這個api是用來檢測dom元素交集的,常見的應用場景之一就是本文提到的對圖片進行懶加載,即:拖動窗口滾動條,到達當前這個圖片的時候,再去讀取掛在自定義屬性(好比:'data-src')上的url地址,以後將該url地址寫到到src屬性上去進行下載、展現這個圖片。所以,咱們關注的重點是:該圖片是否滾動到了當前窗口的可視區域。一般解決的辦法是,監聽窗口元素的scroll事件,在事件處理程序中對圖片的位置作判斷。然而,這麼作的一個弊端是,由於js是單線程的,而scroll事件出現的又很密集,每次都去響應scroll事件可能會影響用戶體驗。html

intersection Observer的誕生就是爲了處理這種相似於上文提到的元素交集檢測。它會觀察咱們的目標元素,當目標元素出如今root元素的可視區域時便會觸發一個(咱們事先放進去的)回調函數,因而咱們能夠在回調函數裏面處理業務邏輯。api

這裏出現了兩個小概念,對應於本文實現的圖片懶加載功能來講:數組

  • 目標元素:指的就是那些咱們須要懶加載的圖片
  • root元素指的就是目標元素的父窗口,好比這裏的圖片的父元素容器

利用intersection Observer實現懶加載

點此查看該案例的stackblitzdom

查看該案例:ide

  1. 在index.html頁面內有一個scrollContainer,在裏面首先是放了幾段文字,以後是5個img元素,並將img的url地址寫在了自定義屬性'data-src'內。
  2. 在css文件內定義了一些樣式,其中,move-in是在咱們對圖片真正進行加載時纔會添加的動畫效果。

如今,不管咱們怎麼拖動滾動條都沒法看見圖片,由於咱們僅僅是把img的url寫在了自定義屬性中而不是src屬性中。接下來,咱們須要利用intersection Observer對這些暫時看不見的圖片元素進行觀察,當確認他們滾動到了窗體的可視區域時,咱們在回調函數中對其進行加載。函數

建立一個observer:

const observer = new IntersectionObserver(callback,option)

option配置root元素和回調函數觸發機制,這裏咱們將scrollContainer這個div設爲root。
callback就是當檢測到目標元素與root元素交集時會調用的函數,形如:動畫

(entrances, observer)=>{
    // entrances是個數組對象,包含了全部的目標元素,一般咱們會遍歷它們,並判斷每個單獨的個體是否與root元素產生了交集,若是是,那麼咱們就會執行一些邏輯
}

鏈接目標元素

剛纔咱們建立了observer,而且設置了它的root元素,如今須要告訴這個observer,咱們須要觀察哪些目標元素與此root元素的交集。
經過observer.observe(target)進行連接url

最終的代碼

const imgs = document.querySelectorAll('img') //獲取全部待觀察的目標元素
var options = {
  root: document.querySelector('.scrollContainer'), 
  rootMargin: '0px',
  threshold: 1.0
}
function lazyLoad(target) {
  const observer = new IntersectionObserver((entrances, observer) => {
    entrances.forEach(entrance => {
      if (entrance.isIntersecting) {
        const img = entrance.target;
        const src = img.getAttribute('data-src');
        img.setAttribute('src', src)
        img.classList.add('move-in')
        observer.disconnect()
      }

    })
  }, options);
  observer.observe(target)
}

imgs.forEach(lazyLoad)
相關文章
相關標籤/搜索