国产成人精品18p,天天干成人网,无码专区狠狠躁天天躁,美女脱精光隐私扒开免费观看

利用原生JS實(shí)現懶加載lazyLoad的三種方法總結

發(fā)布時(shí)間:2021-08-17 12:16 來(lái)源: 閱讀:0 作者:JayDo257248 欄目: JavaScript 歡迎投稿:712375056

目錄

前言

首先我們先搭建好頁(yè)面如下:

<style>
    * {
      padding: 0%;
      margin: 0%;
    }

    .contain img {
      width: 600px;
      height: 400px;
    }

    ul {
      list-style: none;
    }

    li {
      display: inline-block;
    }
  </style>
  
  
  <div class="contain">
    <ul>
       <li><img data-src="./images/iu.jpg"  src='./images/lazy.png' alt=""></li>
      <li><img data-src="./images/iu1.jpg" src='./images/lazy.png' alt=""></li>
      <li><img data-src="./images/iu2.png" src='./images/lazy.png' alt=""></li>
      <li><img data-src="./images/iu3.jpg" src='./images/lazy.png' alt=""></li>
      <li><img data-src="./images/iu4.jpg" src='./images/lazy.png' alt=""></li>
      <li><img data-src="./images/iu5.jpg" src='./images/lazy.png' alt=""></li>
      <li><img data-src="./images/iu6.jpg" src='./images/lazy.png' alt=""></li>
      <li><img data-src="./images/iu7.jpg" src='./images/lazy.png' alt=""></li>
      <li><img data-src="./images/iu8.jpg" src='./images/lazy.png' alt=""></li>
      <li><img data-src="./images/iu9.jpg" src='./images/lazy.png' alt=""></li>
      <li><img data-src="./images/iu10.jpg" src='./images/lazy.png' alt=""></li>
      <li><img data-src="./images/zzf_01.jpg" src='./images/lazy.png' alt=""></li>
    </ul>
  </div
>

我們知道,圖片懶加載是在滾動(dòng)條向下滾動(dòng)時(shí),才判斷圖片是否到達可視區域

于是我們需要在滾動(dòng)監聽(tīng)時(shí)判斷圖片是否即將顯示,所以我們需要將圖片的真實(shí)地址先隱藏起來(lái),即采用自定義屬性 data-src 保存圖片的真實(shí)地址,當滾動(dòng)條滾動(dòng)到圖片能夠看到時(shí)再加載真實(shí)的地址.

下面我們來(lái)看第一個(gè)方法

Method 1: 高度對比

這里我們采用 (元素距頂部的高度 - 頁(yè)面被卷去的高度 <=  瀏覽器可視區的高度) 來(lái)判斷是否符合我們想要的條件.這里我們需要實(shí)時(shí)監聽(tīng)頁(yè)面滾動(dòng)時(shí) 圖片的高度變化

/**
 * 方法一
 * 高度對比
 */
 let imgs = [...document.querySelectorAll('img')]; // 先獲取所有的圖片
 window.addEventListener('scroll', function () {
   
 })

添加完事件后再繼續判斷 圖片是否達到要求,即

 /**
  * 方法一
  * 高度對比
  */
  let imgs = [...document.querySelectorAll('img')]; // 先獲取所有的圖片
  window.addEventListener('scroll', function () {
    lazyLoad(imgs)
  })
  function lazyLoad(imgs) {
    for (var i = 0; i < imgs.length; i++) {
      var height = imgs[i].offsetTop; // 圖片的距頂部的高度
      var wheight = window.innerHeight; // 瀏覽器可視區的高度
      var sheight = document.documentElement.scrollTop; // 頁(yè)面被卷去的高度
      if (height - sheight <= wheight) { // 判斷圖片是否將要出現
        imgs[i].src = imgs[i].dataset.src; // 出現后將自定義地址轉為真實(shí)地址
      }
    }
  }

看起來(lái)還挺簡(jiǎn)單的對吧? 不過(guò)我們還有更簡(jiǎn)單的方法,如下:

Method 2: 使用getBoundingClientRect() 的API

先附上MDN 對getBoundingClientRect() 的解釋

我們可以通過(guò) getBoundingClientRect().top來(lái)獲取元素距視口頂部的距離,于是我們就可以比較getBoundingClientRect().top 和  window.innerHeight 的值的關(guān)系來(lái)實(shí)現懶加載的效果
這里使用了 和屬性

 /**
  * 方法二
  * @params getBoundingClientRect()
  * 可視區API
  */

 let imgs = [...document.querySelectorAll('img')];
 window.addEventListener('scroll', function () {
    imgs.forEach(img => { 
      //這里其實(shí)和Method1的思想一樣,不過(guò)就是簡(jiǎn)潔了一些
      if (img.getBoundingClientRect().top < window.innerHeight) { 
     
        let dataSrc = img.getAttribute(' data-src'); // 獲取 data-src 真實(shí)的地址
        img.setAttribute('src', dataSrc); // 將 真實(shí)的地址 替換為 src屬性
        console.log(img.src);
      }
    })
  })

Method 3: 采用最新的 IntersectionObserver 構造函數

看過(guò)上面兩種方法,那你是否覺(jué)得懶加載還挺簡(jiǎn)單的對吧?

沒(méi)錯,我們寫(xiě)的代碼很少,看起來(lái)很簡(jiǎn)單,但是我們忽略了一個(gè)重要的問(wèn)題:

    圖片替換為真實(shí)的地址之后,如果我們反復的拉動(dòng)滾動(dòng)條,會(huì )一直觸發(fā) if()條件,
   
    所以我在 Method2 方法里給了一個(gè)   console.log(img.src);
   
    目的就是為了讓你看到當有人持續不斷的拉動(dòng)滾動(dòng)條,會(huì )一直打印 console.log(img.src);

那我們怎么去讓圖片真實(shí)地址加載完之后,不再觸發(fā)對它的頻繁操作呢?或者說(shuō)怎么優(yōu)化游覽器的性能呢?

好巧不巧,現在有了一個(gè)新增的構造函數,來(lái)解決我們的頻繁觸發(fā)條件語(yǔ)句的問(wèn)題.

這個(gè)構造函數就是

根據 MDN 上的解釋

  • IntersectionObserver()構造器創(chuàng )建并返回一個(gè)IntersectionObserver對象。 如果指定rootMargin則會(huì )檢查其是否符合語(yǔ)法規定,檢查閾值以確保全部在0.0到1.0之間,并且閾值列表會(huì )按升序排列。如果閾值列表為空,則默認為一個(gè)[0.0]的數組。
  • callback當元素可見(jiàn)比例超過(guò)指定閾值后,會(huì )調用一個(gè)回調函數,此回調函數接受兩個(gè)參數:
    entries一個(gè)IntersectionObserverEntry對象的數組,每個(gè)被觸發(fā)的閾值,都或多或少與指定閾值有偏差。
    observer被調用的IntersectionObserver實(shí)例。

這里我們只使用第一個(gè)參數 callback 這個(gè)回調函數

window.addEventListener('scroll', function () {
// 首先我們先實(shí)例化這個(gè)構造函數
   const observe = new IntersectionObserver(callback);
// 然后寫(xiě)我們需要處理業(yè)務(wù)的回調函數 callback
   const callback = entries => {
        console.log(entries); //我們先打印一下 entries 看看有什么用 
        // 如下圖
    };
}

window.addEventListener('scroll', function () {
   const observe = new IntersectionObserver(callback);
// 然后寫(xiě)我們需要處理業(yè)務(wù)的回調函數 callback
   const callback = entries => {
       // 我們發(fā)現它是個(gè)數組,于是
       entries.forEach(ele => {
           console.log(ele); // 我們再打印一下元素,看看元素里面有什么
           // 如下圖
       })
    };
}

我們找到了 isIntersecting: false 這個(gè)屬性,這個(gè)意思是 是否交叉,根據構造函數的意義我們得知,交叉可以理解為是否被觀(guān)察到

如果被觀(guān)察到, 那我們就讓他的真實(shí)地址替換為 它的 src 屬性 ,并且取消對它的觀(guān)察

 /**
  * 方法三
  * @params   new IntersectionObserver(callback[,options])
  * 觀(guān)察-->構造函數
  */
  window.addEventListener('scroll', function () {
    let imgs = [...document.querySelectorAll('.img')]
    const callback = entries => { // entries 是觀(guān)察的元素數組
        entries.forEach(ele => {
            if (ele.isIntersecting) { // isIntersecting  是否被觀(guān)察到
                const data_src = ele.target.getAttribute('data-src'); //這里基本和 Method1/Method2一樣
                ele.target.setAttribute('src', data_src); // ele.target 是目標元素
                observe.unobserve(ele.target) // 真實(shí)地址替換后 取消對它的觀(guān)察
            }
        })
    };
    const observe = new IntersectionObserver(callback); // 實(shí)例化 IntersectionObserver
    imgs.forEach(image => { 
        observe.observe(image) // observe : 被調用的IntersectionObserver實(shí)例。給每個(gè)圖片添加觀(guān)察實(shí)例
    })
  }

這樣處理,我們就可以不再頻繁的去觸發(fā) if() 條件語(yǔ)句

因為在圖片替換了真實(shí)地址后,我取消了對當前圖片的觀(guān)察,于是,當前圖片已經(jīng)沒(méi)有事件再被觸發(fā),所以這樣對瀏覽器的性能進(jìn)行了極大的優(yōu)化

總結

到此這篇關(guān)于利用原生JS實(shí)現懶加載lazyLoad的三種方法的文章就介紹到這了,更多相關(guān)JS實(shí)現懶加載lazyLoad內容請搜索腳本之家以前的文章或繼續瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng )、來(lái)自本網(wǎng)站內容采集于網(wǎng)絡(luò )互聯(lián)網(wǎng)轉載等其它媒體和分享為主,內容觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如侵犯了原作者的版權,請告知一經(jīng)查實(shí),將立刻刪除涉嫌侵權內容,聯(lián)系我們QQ:712375056,同時(shí)歡迎投稿傳遞力量。

JD又硬又粗又大又长受不了| 337P日本大胆欧洲色噜噜| 中美日韩亚洲综合在线| 亚洲av日韩av天堂影片人人网| 好爽…又高潮了毛片喷水| 欧美亚洲日本国产综合在线美利坚|