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

一文教你學(xué)會(huì)用JS實(shí)現(xiàn)圖片懶加載功能

 更新時(shí)間:2023年07月27日 10:11:09   作者:chenxuyan  
圖片懶加載是日常開(kāi)發(fā)會(huì)經(jīng)常使用的一個(gè)功能,但是在日常中可能使用v-lazy便直接實(shí)現(xiàn)了圖片懶加載,但是本文將通過(guò)原生js來(lái)實(shí)現(xiàn)一下圖片懶加載的功能,感興趣的同學(xué)跟著小編一起來(lái)看看吧

通過(guò)IntersectionObserver實(shí)現(xiàn)圖片懶加載功能

首先來(lái)介紹一下IntersectionObserver,這個(gè)在MDN中有十分詳細(xì)的介紹.可以直接去看原文.這里簡(jiǎn)單介紹一下他的用法.

IntersectionObserver

IntersectionObserver 是一個(gè) JavaScript 的 API,用于觀察目標(biāo)元素與其祖先元素或視窗(viewport)之間的交叉狀態(tài)。它能夠提供一種高效的方式來(lái)檢測(cè)目標(biāo)元素是否進(jìn)入或離開(kāi)視窗,或者與其父元素發(fā)生交叉,從而實(shí)現(xiàn)懶加載、無(wú)限滾動(dòng)、動(dòng)態(tài)加載等功能。IntersectionObserver API 在現(xiàn)代瀏覽器中得到廣泛支持。

屬性:

  • IntersectionObserver.root:表示根元素(root)的可見(jiàn)區(qū)域。它是一個(gè) Document 對(duì)象的引用。默認(rèn)情況下,根元素為視窗(viewport)。你可以指定一個(gè)特定的元素,使其成為觀察器的根元素。如果未指定,則默認(rèn)為視窗。
  • IntersectionObserver.rootMargin:用于擴(kuò)展或縮小根元素的可見(jiàn)區(qū)域。它是一個(gè)字符串,類(lèi)似于 CSS 的 margin 屬性,可以包含像素值或百分比值。例如,"10px 20px 30px 40px" 或者 "5% 10%"。這個(gè)屬性用于擴(kuò)大或縮小根元素的可見(jiàn)區(qū)域,使得在進(jìn)入或離開(kāi)視窗之前,目標(biāo)元素需要提前或推遲一定的距離。
  • IntersectionObserver.thresholds:一個(gè)數(shù)組,表示觸發(fā) IntersectionObserver 回調(diào)的交叉閾值。交叉閾值是一個(gè)介于 0 和 1 之間的值,表示目標(biāo)元素可見(jiàn)區(qū)域與根元素可見(jiàn)區(qū)域相交的百分比。當(dāng)目標(biāo)元素的可見(jiàn)區(qū)域與根元素的可見(jiàn)區(qū)域相交達(dá)到或超過(guò)閾值時(shí),會(huì)觸發(fā)回調(diào)函數(shù)。默認(rèn)情況下,閾值為 [0],表示目標(biāo)元素有任何部分進(jìn)入可見(jiàn)區(qū)域時(shí)都會(huì)觸發(fā)回調(diào)。你可以自定義多個(gè)閾值,以實(shí)現(xiàn)更精確的觸發(fā)條件。

方法:

  • IntersectionObserver.observe(target: Element):將一個(gè)目標(biāo)元素添加到 IntersectionObserver 中進(jìn)行觀察。當(dāng)目標(biāo)元素的交叉狀態(tài)滿足設(shè)定的條件時(shí),會(huì)觸發(fā) IntersectionObserver 的回調(diào)函數(shù)。
  • IntersectionObserver.unobserve(target: Element):停止對(duì)指定目標(biāo)元素的觀察,即使目標(biāo)元素的交叉狀態(tài)滿足條件,也不會(huì)觸發(fā) IntersectionObserver 的回調(diào)函數(shù)。
  • IntersectionObserver.disconnect():停止對(duì)所有目標(biāo)元素的觀察,調(diào)用該方法后,即使目標(biāo)元素的交叉狀態(tài)發(fā)生變化,也不會(huì)觸發(fā) IntersectionObserver 的回調(diào)函數(shù)。
  • IntersectionObserver.takeRecords():返回一個(gè)包含所有觀察目標(biāo)元素的 IntersectionObserverEntry 對(duì)象數(shù)組。每個(gè) IntersectionObserverEntry 對(duì)象包含目標(biāo)元素的交叉狀態(tài)信息,如可見(jiàn)區(qū)域的大小和位置等。

簡(jiǎn)單實(shí)現(xiàn)

圖片獲取:

// globEager是靜態(tài)加載模式
// glob是懶加載模式
// let imgList=import.meta.glob('./assets/*.*',{eager:true}) ----便是靜態(tài)加載模式
let imgList:Record<string,{default:string}>=import.meta.glob('./assets/*.*',{eager:true})
let arr=Object.values(imgList).map((item:any)=>item.default)
console.log(arr);

在很多時(shí)候,獲取圖片列表的方式都是將圖片路徑添加到一個(gè)數(shù)組中,進(jìn)行獲取,十分繁瑣,而上面的這種方式相對(duì)而言要簡(jiǎn)單很多.import.meta.globimport.meta.globEager兩種方式大同小異,但是import.meta.glob這種可以直接實(shí)現(xiàn)圖片懶加載引入,而后面那種則是通過(guò)靜態(tài)資源的方式將圖片進(jìn)行引入.這便是這兩種方式的區(qū)別.由于在這個(gè)dome中要實(shí)現(xiàn)圖片懶加載,所以是使用的是第二種方式引入(在第一種方式加一個(gè){eager:true}便可以達(dá)到第二種引入方式的效果).

先來(lái)看看imgList的輸出結(jié)果:

可以很明顯的看到default就是圖片的路徑,那么只需要將其獲取即可

let arr=Object.values(imgList).map((item:any)=>item.default)

因?yàn)榉祷氐氖且粋€(gè)對(duì)象,所以便可以使用Object.values來(lái)獲取到value,再通過(guò)map遍歷的方式獲取到其default

從而便獲得了其路徑,這種獲取路徑的方式還是比較輕松,且方便的.

再解決完圖片問(wèn)題之后,便是懶加載部分的實(shí)現(xiàn)了.

懶加載實(shí)現(xiàn):

關(guān)于IntersectionObserver的屬性和方法在前面也簡(jiǎn)單的介紹了.同時(shí)也附上了MDN相關(guān)鏈接.這里便不會(huì)再去贅述了.

相關(guān)代碼展示:

let vLazy:Directive<HTMLImageElement,string>=async (el,binging)=>{
  const def=await import('./assets/vue.svg')
  el.src=def.default
  console.log(el);
  const observer=new IntersectionObserver(enr=>{
    console.log(enr[0]);
    if(enr[0].intersectionRatio>0){
      setTimeout(()=>{
        el.src=binging.value
      },2000)
      observer.unobserve(el)
    }
  })
  observer.observe(el)
}

在對(duì)于前面屬性和方法的了解的加持下,看這段代碼屬實(shí)不難.其中定時(shí)器只是為了更好的去呈現(xiàn)懶加載的這個(gè)過(guò)程.

上述代碼中,通過(guò)使用vue的矢量圖來(lái)作為默認(rèn)圖片,當(dāng)未加載時(shí),展示這張圖.看函數(shù)主體:

enr所返回的就是每一個(gè)圖片所返回的IntersectionObserver

因?yàn)橹惶砑恿巳龔垐D片所以返回了三個(gè)對(duì)象,而所需要關(guān)注的就是intersectionRatio這個(gè)屬性,當(dāng)它大于0時(shí),便會(huì)將圖片路徑更換為指定路徑,從而實(shí)現(xiàn)了圖片懶加載,當(dāng)然在實(shí)現(xiàn)這一功能之后,也要關(guān)閉 observer.unobserve(el),不然會(huì)一直關(guān)注這一個(gè).

整體代碼呈現(xiàn):

<template>
<div >
  <div class="card">
    <img v-lazy="item" v-for="(item,index) in arr" :src="item" :key="index" alt="" width="360" height="500" >
  </div>
</div>
</template>
<script setup lang='ts'>
import HelloWorld from './components/HelloWorld.vue';
import type {Directive } from 'vue'
// globEager是靜態(tài)加載模式
// glob是懶加載模式
// let imgList=import.meta.glob('./assets/*.*',{eager:true}) ----便是靜態(tài)加載模式
let imgList:Record<string,{default:string}>=import.meta.glob('./assets/*.*',{eager:true})
let arr=Object.values(imgList).map((item:any)=>item.default)
console.log(arr);
let vLazy:Directive<HTMLImageElement,string>=async (el,binging)=>{
  const def=await import('./assets/vue.svg')
  el.src=def.default
  console.log(el);
  const observer=new IntersectionObserver(enr=>{
    console.log(enr[0]);
    if(enr[0].intersectionRatio>0){
      setTimeout(()=>{
        el.src=binging.value
      },2000)
      observer.unobserve(el)
    }
  })
  observer.observe(el)
}
</script>

到此這篇關(guān)于一文教你學(xué)會(huì)用JS實(shí)現(xiàn)圖片懶加載功能的文章就介紹到這了,更多相關(guān)JS實(shí)現(xiàn)圖片懶加載功能內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論