這篇文章主要講解了實(shí)現(xiàn)一個(gè)Vue自定義指令懶加載的實(shí)例代碼,內(nèi)容清晰明了,對(duì)此有興趣的小伙伴可以學(xué)習(xí)一下,相信大家閱讀完之后會(huì)有幫助。
創(chuàng)新互聯(lián)公司主營(yíng)云南網(wǎng)站建設(shè)的網(wǎng)絡(luò)公司,主營(yíng)網(wǎng)站建設(shè)方案,成都app開(kāi)發(fā),云南h5微信小程序開(kāi)發(fā)搭建,云南網(wǎng)站營(yíng)銷推廣歡迎云南等地區(qū)企業(yè)咨詢
在項(xiàng)目中如果有大量的圖片需要加載的時(shí)候,就可以考慮使用懶加載了,懶加載其實(shí)就是監(jiān)聽(tīng)瀏覽器的滾動(dòng),當(dāng)滾動(dòng)到一定的范圍的時(shí)候就將圖片的真實(shí)路徑賦給src,然后取消監(jiān)聽(tīng)。實(shí)現(xiàn)的方法也比較簡(jiǎn)單,可以通過(guò)懶加載的插件實(shí)現(xiàn),也可以手寫,手寫通過(guò)vue自定義指令來(lái)實(shí)現(xiàn),一般情況自定義指令用的也不多,比較vue自帶的就夠用了,大型復(fù)雜的項(xiàng)目的可能用的多。
什么是圖片懶加載
當(dāng)我們向下滾動(dòng)的時(shí)候圖片資源才被請(qǐng)求到,這也就是我們本次要實(shí)現(xiàn)的效果,進(jìn)入頁(yè)面的時(shí)候,只請(qǐng)求可視區(qū)域的圖片資源這也就是懶加載。
比如我們加載一個(gè)頁(yè)面,這個(gè)頁(yè)面很長(zhǎng)很長(zhǎng),長(zhǎng)到我們的瀏覽器可視區(qū)域裝不下,那么懶加載就是優(yōu)先加載可視區(qū)域的內(nèi)容,其他部分等進(jìn)入了可視區(qū)域在加載。
這個(gè)功能非常常見(jiàn),你打開(kāi)淘寶的首頁(yè),向下滾動(dòng),就會(huì)看到會(huì)有圖片不斷的加載;你在百度中搜索圖片,結(jié)果肯定成千上萬(wàn)條,不可能所有的都一下子加載出來(lái)的,很重要的原因就是會(huì)有性能問(wèn)題。你可以在Network中查看,在頁(yè)面滾動(dòng)的時(shí)候,會(huì)看到圖片一張張加載出來(lái)。
為什么要做圖片懶加載
懶加載是一種網(wǎng)頁(yè)性能優(yōu)化的方式,它能極大的提升用戶體驗(yàn)。就比如說(shuō)圖片,圖片一直是影響網(wǎng)頁(yè)性能的主要元兇,現(xiàn)在一張圖片超過(guò)幾兆已經(jīng)是很經(jīng)常的事了。如果每次進(jìn)入頁(yè)面就請(qǐng)求所有的圖片資源,那么可能等圖片加載出來(lái)用戶也早就走了。所以,我們需要懶加載,進(jìn)入頁(yè)面的時(shí)候,只請(qǐng)求可視區(qū)域的圖片資源。
總結(jié)出來(lái)就兩個(gè)點(diǎn):
1.全部加載的話會(huì)影響用戶體驗(yàn)
2.浪費(fèi)用戶的流量,有些用戶并不像全部看完,全部加載會(huì)耗費(fèi)大量流量。
懶加載原理
圖片的標(biāo)簽是 img
標(biāo)簽,圖片的來(lái)源主要是 src屬性,瀏覽器是否發(fā)起加載圖片的請(qǐng)求是根據(jù)是否有src屬性決定的。
所以可以從 img
標(biāo)簽的 src屬性入手,在沒(méi)進(jìn)到可視區(qū)域的時(shí)候,就先不給 img 標(biāo)簽的 src屬性賦值。
懶加載實(shí)現(xiàn)
實(shí)現(xiàn)效果圖:
Document
監(jiān)聽(tīng)滾動(dòng)根據(jù)offsetTop判斷
const imgs = [...document.getElementsByTagName('img')]; let n = 0; lazyload(); function throttle(fn, wait) { let timer = null; return function(...args) { if(!timer) { timer = setTimeout(() => { timer = null; fn.apply(this, args) }, wait) } } } window.addEventListener('scroll', throttle(lazyload, 200)); function lazyload() { var innerHeight = window.innerHeight; var scrollTop = document.documentElement.scrollTop || document.body.scrollTop; for(let i = n; i < imgs.length; i++) { if(imgs[i].offsetTop < innerHeight + scrollTop) { imgs[i].src = imgs[i].getAttribute("data-src"); n = i + 1; } } }
可能會(huì)存在下面幾個(gè)問(wèn)題:
IntersectionObserver
const imgs = [...document.getElementsByTagName('img')]; // 當(dāng)監(jiān)聽(tīng)的元素進(jìn)入可視范圍內(nèi)的會(huì)觸發(fā)回調(diào) if(IntersectionObserver) { let lazyImageObserver = new IntersectionObserver((entries, observer) => { entries.forEach((entry, index) => { let lazyImage = entry.target; // 相交率,默認(rèn)是相對(duì)于瀏覽器視窗 if(entry.intersectionRatio > 0) { lazyImage.src = lazyImage.getAttribute('data-src'); // 當(dāng)前圖片加載完之后需要去掉監(jiān)聽(tīng) lazyImageObserver.unobserve(lazyImage); } }) }) for(let i = 0; i < imgs.length; i++) { lazyImageObserver.observe(imgs[i]); } }
codePen
vue自定義指令-懶加載
Vue自定義指令
下面的api來(lái)自官網(wǎng)自定義指令:
鉤子函數(shù)
鉤子函數(shù)參數(shù)
指令鉤子函數(shù)會(huì)被傳入以下參數(shù):
實(shí)現(xiàn) v-lazyload 指令
Document
看完上述內(nèi)容,是不是對(duì)實(shí)現(xiàn)一個(gè)Vue自定義指令懶加載的實(shí)例代碼有進(jìn)一步的了解,如果還想學(xué)習(xí)更多內(nèi)容,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。