欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JavaScript實(shí)現(xiàn)圖片懶加載的六種方案

 更新時間:2025年05月09日 10:21:55   作者:儒雅的烤地瓜  
懶加載是一種對網(wǎng)頁性能優(yōu)化的方式,比如,當(dāng)訪問一個網(wǎng)頁的時候,優(yōu)先顯示可視區(qū)域的圖片而不是一次加載全部的圖片,當(dāng)需要顯示時,再發(fā)送請求加載圖片,本文給大家介紹了JavaScript實(shí)現(xiàn)圖片懶加載的六種方案,需要的朋友可以參考下

一、什么是懶加載?

懶加載是一種對網(wǎng)頁性能優(yōu)化的方式,比如,當(dāng)訪問一個網(wǎng)頁的時候,優(yōu)先顯示可視區(qū)域的圖片而不是一次加載全部的圖片,當(dāng)需要顯示時,再發(fā)送請求加載圖片。

懶加載 :延遲加載,對于一個很長的頁面,優(yōu)先加載可視區(qū)域的內(nèi)容,其他部分等進(jìn)入可視區(qū)域時再加載。 

二、為什么要懶加載?

懶加載是一種網(wǎng)頁性能優(yōu)化的方式,它能極大的提升用戶體驗(yàn)。比如一個頁面中有很多圖片,但是首屏只出現(xiàn)幾張,這時如果一次性把圖片全部加載出來會影響性能。這時可以使用懶加載,頁面滾動到可視區(qū)再加載。優(yōu)化首屏加載。

一次性加載全部圖片的話,一方面會影響用戶體驗(yàn);另一方面浪費(fèi)用戶的流量,有些用戶并不想全部看完,全部加載會耗費(fèi)大量流量。 而使用圖片懶加載就會使頁面加載速度快,減輕服務(wù)器壓力,節(jié)約流量,用戶體驗(yàn)好。

當(dāng)頁面需要展示大量圖片時,如果一次性渲染所有圖片,會向服務(wù)器發(fā)出大量請求,導(dǎo)致服務(wù)器響應(yīng)慢,出現(xiàn)頁面卡頓或崩潰等問題。采用懶加載技術(shù)只預(yù)先加載可視區(qū)內(nèi)的圖片,當(dāng)滾動到其他位置時,才去加載這塊區(qū)域的圖片,也可以使用比較小的loading圖片進(jìn)行占位,有效減輕服務(wù)器的壓力,加速頁面渲染,提高用戶體驗(yàn)。     

小結(jié)——懶加載優(yōu)點(diǎn)

  • 避免首次加載時消耗大量時間,降低頁面渲染速度,造成卡頓現(xiàn)象。
  • 按需加載,避免無效圖片的加載,減輕服務(wù)器壓力,節(jié)約網(wǎng)絡(luò)資源。

三、圖片懶加載的實(shí)現(xiàn)原理

  •  基本原理 監(jiān)聽圖片是否位于頁面的可視區(qū)域內(nèi),若在則加載圖片,不在則不加載圖片
  •  實(shí)現(xiàn)方案 自定義屬性-將圖片真實(shí)地址 url 存儲在自定義屬性中,當(dāng)監(jiān)聽到圖片進(jìn)入可視區(qū) 域 時,將自定義屬性值賦值給 img 的 src 屬性

四、圖片懶加載實(shí)現(xiàn)方式

圖像是頁面的一部分,它會提前開始加載。一旦瀏覽器在源代碼中看到它們,就會提示下載。即使圖像被隱藏,即使它位于一個非常長的頁面的底部,也會提前加載。

3.1 方案一:設(shè)置 img 標(biāo)簽屬性 loading=“lazy”

設(shè)置 loading="lazy"允許瀏覽器,延遲加載屏幕外圖像 img 和 iframe,直到用戶滾動到它們附近。

loading屬性支持下面這幾個值:

① lazy:圖片或框架懶加載,也就是元素資源快要被看到的時候加載。

② eager:圖片或框架無視一切進(jìn)行加載。

③ auto:默認(rèn)值。

圖片或框架基于瀏覽器自己的策略進(jìn)行加載。如果HTMLImageElement或者HTMLIFrameElement元素沒有顯式地設(shè)置loading屬性或者loading屬性的值不合法,則都被當(dāng)作’auto’處理。

<img src="" loading="lazy"/>
<iframe src="" loading="lazy"/>
  • Lazy loading加載數(shù)量與屏幕高度有關(guān),高度越小加載數(shù)量越少,但并不是線性關(guān)系。
  • Lazy loading加載數(shù)量與網(wǎng)速有關(guān),網(wǎng)速越慢,加載數(shù)量越多,但并不是線性關(guān)系。
  • 滾動即會觸發(fā)圖片懶加載,而不是滾動一屏后再去加載。
  • 窗口resize尺寸變化也會觸發(fā)圖片懶加載,當(dāng)屏幕高度從小變大的時候。

3.1.1 loading 屬性的兼容

loading 屬性的兼容性如下:

3.1.2 如何判斷當(dāng)前瀏覽器是否支持loading=”lazy”?

下面三種方法都可以:

var isSupportLoading = 'loading' in document.createElement('img');
var isSupportLoading = 'loading' in new Image();
var isSupportLoading = 'loading' in HTMLImageElement.prototype;

例:您可以通過檢查HTMLImageElement.prototype上是否存在loading屬性來判斷當(dāng)前瀏覽器是否支持loading="lazy"特性。以下是一個簡單的JavaScript代碼示例: 

function isLazyLoadingSupported() {
    // 檢查'loading'屬性是否在HTMLImageElement.prototype上定義
    return 'loading' in HTMLImageElement.prototype;
}
 
if (isLazyLoadingSupported()) {
    console.log('Lazy loading is supported.');
} else {
    console.log('Lazy loading is not supported.');
}

如果isLazyLoadingSupported()函數(shù)返回true,則當(dāng)前瀏覽器支持loading="lazy";如果返回false,則不支持。 

3.1.3. 如何獲取loading屬性值

var attrLoading = img.loading;

如果瀏覽器并不支持原生的loading懶加載,則會返回undefined,例如在Firefox瀏覽器下

3.2  方案二:利用JS監(jiān)聽scroll滾動事件

3.2.1. 實(shí)現(xiàn)原理

監(jiān)聽scroll事件,獲取 img 元素相對于視口的頂點(diǎn)位置 el.getBoundingClientRect().top,只要這個值小于瀏覽器的高度 window.innerHeight 就說明進(jìn)入可視區(qū)域,當(dāng)圖片進(jìn)入可視區(qū)域時再去加載圖片資源。

圖片剛開始顯示的是默認(rèn)圖片,當(dāng)進(jìn)入可視區(qū)域時,用 data-src 的真實(shí)圖片地址賦值給 src。

3.2.2. 實(shí)現(xiàn)方案

① 首先給圖片一個占位資源:

<img src="default.jpg" data-src="http://www.xxx.com/target.jpg" />

② clientHeight、scrollTop 和 offsetTop

屬性介紹

獲得瀏覽器窗口(視口)大小: 2組:

1、獲取文檔顯示區(qū) / 網(wǎng)頁可見區(qū)域大小

① 對于Internet Explorer9+、Chrome、Firefox、Opera 以及 Safari

window.innerWidth、window.innerHeight | Window innerWidth 與 innerHeight 屬性 | 參考手冊

window.innertHeight :  瀏覽器窗口的內(nèi)部高度

  • A 表示window的內(nèi)部高度,包含border、paddingmargin以及水平滾動條的高度
  • B 語法:window.innertHeight

window.innerWidth:  瀏覽器窗口的內(nèi)部寬度

  • A 表示window的內(nèi)部寬度,包括 border、padding、margin以及垂直滾動條的寬度
  • B 語法:window.innerWidth

② 對于 Internet Explorer 8、7、6、5

element.clientHeight、element.clientWidth

document.body.clientHeight : 表示的是<body>元素的內(nèi)容區(qū)域高度

  • A 表示的是<body>元素的內(nèi)容區(qū)域高度,包含padding 不包含 border 和 margin以及水平滾動條的高度
  • B 語法:element.clientHeight

document.body.clientWidth : 表示的是<body>元素的內(nèi)容區(qū)域?qū)挾?/p>

  • A 表示的是<body>元素的內(nèi)容區(qū)域?qū)挾龋?strong>包含padding 不包含 border 和 margin以及垂直滾動條的寬度
  • B 語法:document.body.clientWidth

或者

document.documentElement.clientHeight:表示的是整個視口的高度

  • A 表示的是整個視口的高度,即整個網(wǎng)頁的可視區(qū)域高度,包含padding 不包含 border 和 margin以及水平滾動條的高度
  • B 語法:document.documentElement.clientHeight

document.documentElement.clientWidth:表示的是整個視口的寬度

  • A 表示的是整個視口的寬度,即整個網(wǎng)頁的可視區(qū)域?qū)挾龋?strong>包含padding 不包含 border 和 margin以及垂直滾動條的寬度
  • B 語法:document.documentElement.clientWidth

實(shí)用的獲取頁面大小的瀏覽器兼容性JavaScript 方案(涵蓋所有瀏覽器):

var w=window.innerWidth || document.documentElement.clientWidth
|| document.body.clientWidth;
 
var h=window.innerHeight || document.documentElement.clientHeight
|| document.body.clientHeight;

補(bǔ):‌document.documentElement.clientHeight與document.body.clientHeight的主要區(qū)別在于它們代表的網(wǎng)頁區(qū)域不同。

  • document.documentElement.clientHeight‌ 表示的是整個視口的高度,即整個網(wǎng)頁的可視區(qū)域高度。它包括了padding但排除了border、水平滾動條和margin的高度‌。
  • document.body.clientHeight‌ 表示的是<body>元素的內(nèi)容區(qū)域高度,通常不包括滾動條的高度。如果<body>元素沒有設(shè)置高度或者其高度小于其內(nèi)部內(nèi)容的高度,則可能會顯示不全‌。

影響這兩個屬性值的主要因素包括‌:

  • CSS設(shè)置‌:如果<body>元素的CSS高度被設(shè)置為100%,并且包含了所有的內(nèi)容高度,那么document.body.clientHeight將反映整個視口的高度。相反,如果<html>元素的CSS高度被設(shè)置為100%,而<body>元素的高度未明確設(shè)置,那么document.documentElement.clientHeight將反映整個視口的高度,而document.body.clientHeight可能為0或小于視口高度‌。
  • DOCTYPE聲明‌:缺少DOCTYPE聲明可能會導(dǎo)致document.documentElement.clientHeight為0,因?yàn)闉g覽器可能無法正確解析文檔類型,從而影響元素的默認(rèn)顯示和尺寸計(jì)算‌。

實(shí)際應(yīng)用中的注意事項(xiàng)‌:

  • 在開發(fā)過程中,應(yīng)注意DOCTYPE的聲明和CSS的設(shè)置,以確保頁面布局的正確顯示。如果需要獲取整個視口的高度,應(yīng)使用document.documentElement.clientHeight;如果需要獲取<body>元素的內(nèi)容高度,應(yīng)確保<body>元素的CSS高度設(shè)置正確‌。
  • 在調(diào)試頁面布局時,可以使用瀏覽器的開發(fā)者工具查看這些屬性的值,幫助定位問題所在‌

補(bǔ):document.body.clientWidth和window.innerWidth的主要區(qū)別在于是否包含滾動條和邊框。

document.body.clientWidth表示瀏覽器窗口中文檔主體部分的視口寬度,這個值包括了文檔主體的內(nèi)容區(qū)域?qū)挾龋话L動條的寬度。如果文檔主體有邊框,這個值也不包括邊框的寬度。相反,window.innerWidth表示瀏覽器窗口的內(nèi)視口寬度,這個值包括了視口內(nèi)部的全部寬度,即包括了滾動條的寬度(如果存在的話)‌。

此外,document.body.clientWidthwindow.innerWidth的區(qū)別還受到
文檔模式的影響。在混雜模式(BackCompat)下,document.body.clientWidthwindow.innerWidth的值可能不同,因?yàn)榛祀s模式下文檔主體的寬度計(jì)算不包括滾動條。而在標(biāo)準(zhǔn)模式(CSS1Compat)下,兩者的值通常是相同的,因?yàn)榇藭r文檔的寬度計(jì)算包括了滾動條‌

2、完整窗口大小: window.outerWidth   window.outerHeight

offsetTop : 距離父級元素頂部的高度

  • A 表示當(dāng)前元素相對于其offsetParent元素的頂部內(nèi)邊距的距離
  • B 語法:element.offsetTop

scrollTop : 網(wǎng)頁被卷去的距離

A 表示在有滾動條時,滾動條向下滾動的距離也就是元素頂部被遮住部分的高度
B 語法:element.scrollTop                       

③ 接著,通過監(jiān)聽 scroll 事件來判斷圖片是否到達(dá)視口

let img = document.getElementsByTagName("img");
let num = img.length;
let count = 0; //存儲圖片加載到的位置,避免每次都從第一張圖片開始遍歷
 
lazyload(); // 首次加載別忘了顯示圖片
 
window.addEventListener('scroll', throttle(lazyload, 200)); // throttle是節(jié)流函數(shù),自己實(shí)現(xiàn)一下
 
//offsetTop是元素與offsetParent的距離,循環(huán)獲取直到頁面頂部
function getTop(el) {
    var T = el.offsetTop;
    while(el = el.offsetParent) {
        T += el.offsetTop;
    }
    return T;
}
 
function lazyload() {
  let viewHeight = document.documentElement.clientHeight || document.body.clientHeight;//視口高度
  let scrollTop = document.documentElement.scrollTop || document.body.scrollTop;//滾動條卷去的高度
  for(let i = count; i <num; i++) {
    // 元素現(xiàn)在已經(jīng)出現(xiàn)在視口中
    if(getTop(img[i]) < scrollTop + viewHeight) {
      if(img[i].getAttribute("src") !== "default.jpg") continue;
      img[i].src = img[i].getAttribute("data-src");
      count ++;
    } else {
      break; // 提早退出
    }
  }
}

offsetParent 就是距離該子元素最近的進(jìn)行過定位的父元素(position:absolute或relative 或fixed),如果其父元素中不存在定位,則offsetParent為:body元素

小結(jié):用JS監(jiān)測這個方式主要是利用整體距離實(shí)現(xiàn)

(1)屬性介紹:參看上面

(2)實(shí)現(xiàn)方法

可以用image.offsetTop <= document.documentElement.clientHeight + document.documentElement.scrollTop 判斷圖片是否可以在可視區(qū)域內(nèi)。即判斷圖像的offsetTop(距離頂部的高度)- scrollTop(頁面被卷去的高度)<=window.innerHeight(可視區(qū)高度)才加載

  • 圖片元素位置的頂部距離:offsetTop
  • 滾動距離的最下端:scrollTop+clientHeight
  // html 標(biāo)簽結(jié)構(gòu)
  <img data-src="./public/image/VCG211430870249.jpg" src="./public/image/默認(rèn).jpg" alt="">
  <img data-src="./public/image/VCG211430987515.jpg" src="./public/image/默認(rèn).jpg" alt="">
  <img data-src="./public/image/VCG211431054751.jpg" src="./public/image/默認(rèn).jpg" alt="">
  <img data-src="./public/image/VCG211435102490.jpg" src="./public/image/默認(rèn).jpg" alt="">
  <img data-src="./public/image/VCG211438229829.jpg" src="./public/image/默認(rèn).jpg" alt="">
  <img data-src="./public/image/VCG211438109615.jpg" src="./public/image/默認(rèn).jpg" alt="">
<script>
  // 1 獲取全部圖片的DOM節(jié)點(diǎn)
  // 注意:querySelectorAll 值為偽數(shù)組利用擴(kuò)展運(yùn)算符轉(zhuǎn)為真數(shù)組
  const images = [...document.querySelectorAll('img')]
  // 2 監(jiān)聽頁面滾動事件
  window.addEventListener('scroll', lazyLoad)
  // 3 定義頁面滾動的處理函數(shù)
  function lazyload(e) {
    // 3.1 獲取屏幕的可視高度
    const clientHeight = document.documentElement.clientHeight
    // 3.2 獲取屏幕的滾動距離
    const scrollTop = document.documentElement.scrollTop
    for (let i = 0; i < images.length; i++) {
      if (images[i].offsetTop < clientHeight + scrollTop) {
        images[i].setAttribute('src', images[i].getAttribute('data-src'))
      }
    }
  }
</script>

3.3 方案三:利用元素的 getBoundingClientRect 方法實(shí)現(xiàn)

getBoundingClientRect() 方法返回元素相對視口左上角的偏移量以及元素本身長寬,單位:px。

修改上述 lazyload 函數(shù)

function lazyload() {
  let viewHeight = document.documentElement.clientHeight || document.body.clientHeight;
  for (let i = count; i < num; i++) {
    // 元素現(xiàn)在已經(jīng)出現(xiàn)在視口中
    if (img[i].getBoundingClientRect().top < viewHeight) {
      if (img[i].getAttribute("src") !== "default.jpg") continue;
      img[i].src = img[i].getAttribute("data-src");
      count++;
    } else {
      break;
    }
  }
}

小結(jié):我們再來舉個例子,總結(jié)一下利用getBoundingClientRect 方法實(shí)現(xiàn)圖片懶加載。

(1)屬性介紹:

利用 getBoundingClientRect()方法實(shí)時獲取物體的動態(tài)位置

(2)實(shí)現(xiàn)方法:

步驟 1:監(jiān)聽頁面滾動事件,lazyLoad為頁面滾動時的處理函數(shù),在本節(jié)為處理圖片懶加載。

步驟 2:判斷圖片是否處于可視區(qū)域內(nèi)

(1)若距離頂部top(或bottom)小于頁面的整體高度window.innerHeight

(2)若距離左側(cè)left(或右側(cè)right)小于頁面的整體寬度window.innerWidth

(3)同時圖片的底部bottom (或頂部top) 與圖片的右側(cè)right(左側(cè)left)距頁面頂部、左側(cè)的距離均大于0,則說明該圖在屏幕的可視區(qū)域內(nèi)。 

為了提高復(fù)用性,我們可以將它封裝成一個自定義函數(shù)isVisible,將每張圖片作為參數(shù)傳入該函數(shù),并返回truefalse

// 可視區(qū)域判斷函數(shù)
  function isVisible(img) {
    // 判斷是否在可視區(qū)域,并返回true或false
    const imgRect = img.getBoundingClientRect() // getBoundingClientRect 獲取圖片的動態(tài)信息
    return imgRect.bottom > 0 && imgRect.top < (window.innerHeight|| document.documentElement.clientHeight) && imgRect.right > 0 && imgRect.left < (window.innerWidth||document.documentElement.clientWidth)
  }

步驟 3:定義圖片懶加載時的處理事件,監(jiān)聽所有的img,判斷該img是否處于可視范圍內(nèi)。

querySelectorAll 獲取的元素為類數(shù)組對象,需要轉(zhuǎn)為真數(shù)組,否則無法使用數(shù)組的某些方法

// 獲取所有的img元素,并利用擴(kuò)展運(yùn)算符轉(zhuǎn)為真數(shù)組
const images = [...document.querySelectorAll('img')]

步驟 4:對每張圖片進(jìn)行監(jiān)聽,利用自定義函數(shù)isVisible判斷是否在可視區(qū)域內(nèi)

(1)若處于可視區(qū)域:將自定義的data-src值,賦值給真正的src屬性值,其中 data-src存儲圖片的URL地址,并刪除該元素防止重復(fù)加載

(2)若不處于可視區(qū)域:return 不做處理

// 利用循環(huán)判斷每張圖片是否屬于可視區(qū)域
function lazyLoad(){
    for (let i = 0; i < images.length; i++) {
    // isVisible是否該圖片位于可視區(qū)域 返回true 或false
      if (isVisible(images[i])) {
        // 將元素的自定義屬性 data-src 賦值給元素的 src 屬性
        // 等價(jià)于:img.setAttribute('src', img.getAttribute('data-src'))
        images[i].src = images[i].dataset.src 
        // 防止重復(fù)被遍歷 加載完之后 刪除元素不再加載
        images.splice(i, 1)
        i--
      }
    }
}
lazyLoad()

getBoundingClientRect()方法的缺點(diǎn):這個屬性頻繁計(jì)算會引發(fā)頁面的重繪,可能會對頁面的性能造成影響。 

3.4. 方案四:IntersectionObserver

有兼容性問題。這是瀏覽器內(nèi)置的一個API,實(shí)現(xiàn)了監(jiān)聽window的scroll事件、判斷是否在視口中以及節(jié)流三大功能。

let img = document.getElementsByTagName("img");
 
const observer = new IntersectionObserver(changes => {
  //changes 是被觀察的元素集合
  for(let i = 0, len = changes.length; i < len; i++) {
    let change = changes[i];
    // 通過這個屬性判斷是否在視口中
    if(change.isIntersecting) {
      const imgElement = change.target;
      imgElement.src = imgElement.getAttribute("data-src");
      observer.unobserve(imgElement);
    }
  }
})
Array.from(img).forEach(item => observer.observe(item));

這樣就很方便地實(shí)現(xiàn)了圖片懶加載,當(dāng)然這個IntersectionObserver也可以用作其他資源的預(yù)加載,功能非常強(qiáng)大。原文鏈接:https://blog.csdn.net/qq_44741577/article/details/139324747

小結(jié):關(guān)于IntersectionObserver

Intersection Observer是一個比較新的api,他允許你追蹤目標(biāo)元素與其祖先元素或視窗的交叉狀態(tài),用他來檢測圖片是否進(jìn)入視口非常方便,不用再像之前綁定事件、計(jì)算距離等。

(1)屬性介紹:

  • 利用Intersection Observer實(shí)例上的observe和unobserve方法,注冊或取消監(jiān)聽事件。
  • 利用isIntersecting方法,判斷該圖片是否處于圖片與屏幕可視區(qū)域的交叉范圍內(nèi)。
  • 注意:Intersection Observer實(shí)例會監(jiān)聽交叉狀態(tài),即出現(xiàn)和消失(觸發(fā)兩次),出現(xiàn)交叉狀態(tài)后會去調(diào)用new的時候傳入的callback回調(diào)函數(shù)

(2)實(shí)現(xiàn)方法:

步驟 1: 監(jiān)聽頁面滾動事件,lazyLoad為頁面滾動時的處理函數(shù),在本節(jié)為處理圖片懶加載。

window.addEventListener('scroll', lazyLoad)

步驟 2: 創(chuàng)建圖片與可視區(qū)域交叉實(shí)例

callback

  • 此為傳入的回調(diào)函數(shù),用于當(dāng)處于交叉狀態(tài)改變時進(jìn)行的處理函數(shù)
  • 該函數(shù)會被觸發(fā)2次:圖片進(jìn)入視野時+圖片離開視野時
 const observer = new IntersectionObserver(callback)

步驟 3: 利用observer實(shí)例上的.observe(img)方法,給每張圖片綁定觀察事件

// 給每一個圖片綁定觀察方法
  imagess.forEach(img => {
    // 圖片進(jìn)入視野+離開視野時會觸發(fā)callback回調(diào)函數(shù)
    observer.observe(img)
  })

步驟 4: 定義圖片的懶加載事件

imgArr:

  • 可以獲得包含所有圖片的isIntersecting屬性的集合,該屬性可判斷是否在交叉區(qū)域內(nèi)
  • target為該圖片的標(biāo)簽元素

// callback 接收的參數(shù)為帶有監(jiān)聽所有圖片交叉屬性的集合
const callback = (imgArr) => {
  console.log("視圖交叉時觸發(fā),離開交叉時也觸發(fā)", imgArr);
  imgArr.forEach((e) => {
    // 判斷是否在視野區(qū)域
    if (e.isIntersecting) {
      e.target.src = e.target.dataset.src;
      // 取消監(jiān)聽,避免重復(fù)加載同一張圖片
      observer.unobserve(e.target);
    }
  });
};

(3)完整代碼:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
 
  <body>
    <img data-src="./public/image/VCG211430870249.jpg" src="./public/image/默認(rèn).jpg" alt="" />
    <img data-src="./public/image/VCG211430987515.jpg" src="./public/image/默認(rèn).jpg" alt="" />
    <img data-src="./public/image/VCG211431054751.jpg" src="./public/image/默認(rèn).jpg" alt="" />
    <img data-src="./public/image/VCG211435102490.jpg" src="./public/image/默認(rèn).jpg" alt="" />
    <img data-src="./public/image/VCG211438229829.jpg" src="./public/image/默認(rèn).jpg" alt="" />
    <img data-src="./public/image/VCG211438109615.jpg" src="./public/image/默認(rèn).jpg" alt="" />
    <script>
      // intersectionObserver 交叉觀察 : 目標(biāo)元素和可視窗口會產(chǎn)生交叉區(qū)域
      const imagess = [...document.querySelectorAll("img")];
      // 2.1 創(chuàng)建視覺交叉的觀察實(shí)例
      const observer = new IntersectionObserver(callback);
      // 2.2 給每一個圖片綁定觀察方法
      imagess.forEach((img) => {
        // 2.3 圖片進(jìn)入視野+離開視野時觸發(fā) - 回調(diào)
        observer.observe(img);
      });
      // callback 接收的參數(shù)為帶有監(jiān)聽所有圖片交叉屬性的集合
      const callback = (imgArr) => {
        console.log("視圖交叉時觸發(fā),離開交叉時也觸發(fā)", imgArr);
        imgArr.forEach((e) => {
          // 判斷是否在視野區(qū)域
          if (e.isIntersecting) {
            e.target.src = e.target.dataset.src;
            // 取消觀察追蹤,避免重復(fù)加載同一張圖片
            observer.unobserve(e.target);
          }
        });
      };
    </script>
  </body>
</html>

3.5 方案五:利用element-ui 的<el-image>組件的lazy屬性開啟懶加載功能

使用element-ui 的<el-image v-for="url in urls" :key="url" :src="url" lazy></el-iamge>可通過lazy開啟懶加載功能,當(dāng)圖片滾動到可視范圍內(nèi)才會加載。

具體實(shí)現(xiàn)代碼:element-ui的 <el-image> Element - The world's most popular Vue UI framework 

<div class="demo-image__lazy">
  <el-image v-for="url in urls" :key="url" :src="url" lazy></el-image>
</div>
 
<script>
  export default {
    data() {
      return {
        urls: [
          'https://fuss10.elemecdn.com/a/3f/3302e58f9a181d2509f3dc0fa68b0jpeg.jpeg',
          'https://fuss10.elemecdn.com/1/34/19aa98b1fcb2781c4fba33d850549jpeg.jpeg',
          'https://fuss10.elemecdn.com/0/6f/e35ff375812e6b0020b6b4e8f9583jpeg.jpeg',
          'https://fuss10.elemecdn.com/9/bb/e27858e973f5d7d3904835f46abbdjpeg.jpeg',
          'https://fuss10.elemecdn.com/d/e6/c4d93a3805b3ce3f323f7974e6f78jpeg.jpeg',
          'https://fuss10.elemecdn.com/3/28/bbf893f792f03a54408b3b7a7ebf0jpeg.jpeg',
          'https://fuss10.elemecdn.com/2/11/6535bcfb26e4c79b48ddde44f4b6fjpeg.jpeg'
        ]
      }
    }
  }
</script>

3.6 方案六:使用vue-lazyLoad插件實(shí)現(xiàn)

使用vue-lazyLoad插件實(shí)現(xiàn),安裝【npm i vue-lazyload -S】,main.ts中進(jìn)行注冊

//main.ts
import VueLazyload from 'vue-lazyload'
app.use(VueLazyload,
    {preLoad: 1.3, //預(yù)加載的寬高比loading: 
    loadimage:"./assets/vue.svg", //圖片加載狀態(tài)下顯示的圖片
    // error: "", //圖片加載失敗時顯示的圖片
    attempt: 1, // 加載錯誤后最大嘗試次數(shù)
})

頁面中通過v-lazy使用

//xx.vue
<template>
  <div>
    <div v-for="item in arr" :key="item">
      <img v-lazy="item" width="600" height="200" alt="" />
    </div>
  </div>
</template>
 
<script lang="ts" setup>
//glob是懶加載模式,globEager靜態(tài)加載
let imageList: Record<string, { default: string }> = import.meta.glob(
  "../assets/images/*.*",
  { eager: true }
);
let arr = Object.values(imageList).map((v) => v.default);
</script>
 
<style lang="scss" scoped></style>

使用vite的兩種文件導(dǎo)入方式

  • 【import.meta.glob("/xx")】方式 為懶加載模式,動態(tài)導(dǎo)入,構(gòu)建時,會分離為獨(dú)立的 chunk,該方式導(dǎo)入使用()=>import("/xx"),跟路由懶加載是一樣的導(dǎo)入方式。
  • 【import.meta.globEager("/xx")】以及【import.meta.glob("/xx",{eager:true})】為靜態(tài)加載

 打印imageList如圖

以上就是JavaScript實(shí)現(xiàn)圖片懶加載的六種方案的詳細(xì)內(nèi)容,更多關(guān)于JavaScript圖片懶加載的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Bootstrap Paginator+PageHelper實(shí)現(xiàn)分頁效果

    Bootstrap Paginator+PageHelper實(shí)現(xiàn)分頁效果

    這篇文章主要為大家詳細(xì)介紹了Bootstrap Paginator+PageHelper實(shí)現(xiàn)分頁效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-12-12
  • uni-app低成本封裝一個取色器組件的簡單方法

    uni-app低成本封裝一個取色器組件的簡單方法

    最近想實(shí)現(xiàn)一個uniapp取色器組件,實(shí)現(xiàn)后發(fā)現(xiàn)效果還不錯,下面這篇文章主要給大家介紹了關(guān)于uni-app低成本封裝一個取色器組件的相關(guān)資料,文中通過圖文介紹的介紹的非常詳細(xì),需要的朋友可以參考下
    2023-02-02
  • 如何用RxJS實(shí)現(xiàn)Redux Form

    如何用RxJS實(shí)現(xiàn)Redux Form

    這篇文章主要介紹了如何用RxJS實(shí)現(xiàn)Redux Form,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-12-12
  • Typescript實(shí)現(xiàn)隊(duì)列的示例代碼

    Typescript實(shí)現(xiàn)隊(duì)列的示例代碼

    隊(duì)列作為一種數(shù)據(jù)結(jié)構(gòu),在現(xiàn)實(shí)生活中它可應(yīng)用于電影院、自助餐廳等場合,本文主要介紹了Typescript實(shí)現(xiàn)隊(duì)列的示例代碼,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-08-08
  • JavaScript運(yùn)動框架 多物體任意值運(yùn)動(三)

    JavaScript運(yùn)動框架 多物體任意值運(yùn)動(三)

    這篇文章主要為大家詳細(xì)介紹了JavaScript運(yùn)動框架的第三部分,多物體任意值運(yùn)動,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-05-05
  • 一文讓你快速了解JavaScript棧

    一文讓你快速了解JavaScript棧

    這篇文章主要介紹了一文讓你快速了解JavaScript棧,棧全稱為堆棧,是一種先進(jìn)后出的的數(shù)據(jù)結(jié)構(gòu),棧中只有兩種基本操作,也就是插入和刪除,也就是入棧和出棧操作,棧只有一端可以進(jìn)行入棧和出棧操作,我們將其稱為棧頂,另一端稱其為棧底
    2022-07-07
  • js驗(yàn)證電話號碼與手機(jī)支持+86的正則表達(dá)式

    js驗(yàn)證電話號碼與手機(jī)支持+86的正則表達(dá)式

    本篇文章主要介紹了js驗(yàn)證電話號碼與手機(jī)支持+86的正則表達(dá)式。需要的朋友可以過來參考下,希望對大家有所幫助
    2014-01-01
  • js循環(huán)map 獲取所有的key和value的實(shí)現(xiàn)代碼(json)

    js循環(huán)map 獲取所有的key和value的實(shí)現(xiàn)代碼(json)

    這篇文章主要介紹了js循環(huán)map 獲取所有的key和value的實(shí)現(xiàn)代碼(json),需要的朋友可以參考下
    2018-05-05
  • js控制的遮罩層實(shí)例介紹

    js控制的遮罩層實(shí)例介紹

    把項(xiàng)目里很土的彈窗,改成了遮罩層顯示,現(xiàn)在感覺好多了。在這里創(chuàng)建一個div和body一樣大小,這樣就可以把整個頁面全部蓋住了,具體實(shí)現(xiàn)祥看本文,希望可以幫助到你
    2013-05-05
  • js實(shí)現(xiàn)改進(jìn)的仿藍(lán)色論壇導(dǎo)航菜單效果代碼

    js實(shí)現(xiàn)改進(jìn)的仿藍(lán)色論壇導(dǎo)航菜單效果代碼

    這篇文章主要介紹了js實(shí)現(xiàn)改進(jìn)的仿藍(lán)色論壇導(dǎo)航菜單效果代碼,涉及JavaScript頁面元素的遍歷及樣式動態(tài)變換技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-09-09

最新評論