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、padding、margin以及水平滾動條的高度
- 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.clientWidth
和window.innerWidth
的區(qū)別還受到
文檔模式的影響。在混雜模式(BackCompat)下,document.body.clientWidth
和window.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ù),并返回true
或false
// 可視區(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)分頁效果
這篇文章主要為大家詳細(xì)介紹了Bootstrap Paginator+PageHelper實(shí)現(xiàn)分頁效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-12-12如何用RxJS實(shí)現(xiàn)Redux Form
這篇文章主要介紹了如何用RxJS實(shí)現(xiàn)Redux Form,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-12-12Typescript實(shí)現(xiàn)隊(duì)列的示例代碼
隊(duì)列作為一種數(shù)據(jù)結(jié)構(gòu),在現(xiàn)實(shí)生活中它可應(yīng)用于電影院、自助餐廳等場合,本文主要介紹了Typescript實(shí)現(xiàn)隊(duì)列的示例代碼,具有一定的參考價(jià)值,感興趣的可以了解一下2024-08-08JavaScript運(yùn)動框架 多物體任意值運(yùn)動(三)
這篇文章主要為大家詳細(xì)介紹了JavaScript運(yùn)動框架的第三部分,多物體任意值運(yùn)動,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-05-05js驗(yàn)證電話號碼與手機(jī)支持+86的正則表達(dá)式
本篇文章主要介紹了js驗(yàn)證電話號碼與手機(jī)支持+86的正則表達(dá)式。需要的朋友可以過來參考下,希望對大家有所幫助2014-01-01js循環(huán)map 獲取所有的key和value的實(shí)現(xiàn)代碼(json)
這篇文章主要介紹了js循環(huán)map 獲取所有的key和value的實(shí)現(xiàn)代碼(json),需要的朋友可以參考下2018-05-05js實(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