日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

20行代碼,封裝一個 React 圖片懶加載組件

來源: 責編: 時間:2024-03-20 08:50:18 194觀看
導讀一、如何判斷圖片進入視口我們可以使用傳統的方式,監聽頁面的 scroll 事件,然后調用目標函數的 getBoundingClientRect 方法,得到目標元素在網頁中的位置信息。但是我并不喜歡監聽 scroll 事件。因為他會大量的執行,并且

xbn28資訊網——每日最新資訊28at.com

一、如何判斷圖片進入視口

我們可以使用傳統的方式,監聽頁面的 scroll 事件,然后調用目標函數的 getBoundingClientRect 方法,得到目標元素在網頁中的位置信息。xbn28資訊網——每日最新資訊28at.com

但是我并不喜歡監聽 scroll 事件。因為他會大量的執行,并且 getBoundingClientRect 是一個同步方法,都在主線程上運行,當其頻繁執行時可能會導致性能出現問題。xbn28資訊網——每日最新資訊28at.com

我們可以使用另外一種方式來做到同樣的效果。他就是 IntersectionObserver。xbn28資訊網——每日最新資訊28at.com

var observer = new IntersectionObserver(callback[, option])

IntersectionObserver 提供了一種異步觀察目標元素與其祖先元素或者頂級文檔 viewport 交叉狀態的方法。其祖先元素或者視口,被稱為根 root。當目標元素與根元素在視圖上產生交集時,回調函數就會執行。xbn28資訊網——每日最新資訊28at.com

我們也可以在 options 中,自定義配置 root 元素。xbn28資訊網——每日最新資訊28at.com

let options = {  root: document.querySelector("#scrollArea"),  rootMargin: "0px",  threshold: 1.0,};let observer = new IntersectionObserver(callback, options);

options 接受三個參數。xbn28資訊網——每日最新資訊28at.com

root

自定義目標元素的根節點。該節點必須是目標元素的祖先元素。如果未指定,默認為視口。xbn28資訊網——每日最新資訊28at.com

rootMargin

根元素周圍的邊距。其值可以類似于 CSS 的 margin 屬性,例如 10px 20px 30px 40px,以此表示上、右、下、左。這些值夜可以是百分比。在計算交叉點之前,這組值用于增大或者縮小根元素邊框的每一側,默認為 0。xbn28資訊網——每日最新資訊28at.com

threshold

一個數字或者一組數字。表示目標可見度達到多少百分比時,回調函數就應該執行。例如,如果我希望交叉部分每超過目標元素 25% 就執行,那么我就傳入 [0, 0.25, 0.5, 0.75, 1]. 默認值為 0。xbn28資訊網——每日最新資訊28at.com

創建的實例有 4 個方法可以讓我們使用。xbn28資訊網——每日最新資訊28at.com

  • observer.disconnect() 停止監聽。
  • observer.observe(element) 開始監聽目標元素。
  • observer.takRecords() 返回所有目標元素的信息對象數組。
  • observer.unobserve(element)停止監聽目標元素。

回調函數執行時,接收一個參數,該參數為回調函數提供目標對象的位置信息,一共有六個屬性。xbn28資訊網——每日最新資訊28at.com

{  // 回調執行的時間  time: 3893.92,    // 被觀察的目標對象  target: element    // 根元素位置信息  rootBounds: ClientRect {    bottom: 920,    height: 1024,    left: 0,    right: 1024,    top: 0,    width: 920  },    // 目標元素位置信息  boundingClientRect: ClientRect {     // ...  },    // 交叉區域矩形的位置大小信息  intersectionRect: ClientRect {    // ...  },    // 元素可見度比例  intersectionRatio: 0.54,}

該參數返回一個數組包含一個或者多個元素的位置信息。xbn28資訊網——每日最新資訊28at.com

二、圖片懶加載原理

在瀏覽器中,展示一張圖片,我們使用的是 img 標簽。img 標簽有一個必須傳入的屬性 src,當我們不傳入 src 時,圖片無法加載,一旦傳入 src,那么圖片就會立即開始加載。xbn28資訊網——每日最新資訊28at.com

因此,我們需要做的事情就是,當圖片沒有出現在可視區域時,不傳入正確的 src 屬性,當通過上述的方法判斷圖片已經出現在可視區域,我們就傳入正確的 src,此時圖片會立即加載。xbn28資訊網——每日最新資訊28at.com

三、代碼實現

首先,我們封裝的新組件,一定要繼承原有 img 標簽的所有能力。先定義一個 Props 類型聲明,目前我們并不需要擴展其他的屬性,暫時先這樣,未來會根據需求的變動逐漸新增新的屬性值。xbn28資訊網——每日最新資訊28at.com

interface LazyLoadProps extends DetailedHTMLProps<ImgHTMLAttributes<HTMLImageElement>, HTMLImageElement> {  }

然后我們我要的事情是,除了 src 屬性,我們要把其他屬性全部直接傳給 img 標簽,具體方式如下:xbn28資訊網——每日最新資訊28at.com

export default function LazyLoad(props: LazyLoadProps) {  const {src = '', ...other} = props    return (    <img {...other} />  )}

然后我們需要定義一個 ref 屬性,用于獲取 img 標簽的元素對象。xbn28資訊網——每日最新資訊28at.com

export default function LazyLoad(props: LazyLoadProps) {  const {src = '', ...other} = props  const img = useRef(null)  return (    <img ref={img} {...other} />  )}

準備工作做好之后,我們最后只需要借助 useEffect 聲明 IntersectionObserver 實例然后監聽圖片元素即可。xbn28資訊網——每日最新資訊28at.com

export default function LazyLoad(props: LazyLoadProps) {  const {src = '', ...other} = props  const [URL, setURL] = useState('')  const img = useRef(null)  useEffect(() => {    var io = new IntersectionObserver((entries) => {      // @ts-ignore      if (entries[0].intersectionRatio > 0) {        setURL(src)        img.current && io.unobserve(img.current)      }    }, {})       if (img.current) {      io.observe(img.current)    }  }, [])  return (    <img ref={img} src={URL} {...other} />  )}

這樣,一個滿足基本要求的圖片懶加載組件就封裝好了。xbn28資訊網——每日最新資訊28at.com

四、擴展思考

在我們做首屏優化的時候,為了能夠達到最快的速度渲染頁面,圖片的加載往往也需要延后,但是又不能延后太多。因此此時的問題是,圖片已經出現在可視區域了,我們又應該如何做才能做到懶加載呢?xbn28資訊網——每日最新資訊28at.com

在實踐中可能還會遇到的需求變動是,給圖片添加一個占位符。然后占位符元素與圖片元素的切換不是立即發生的,而是要等到我們確保圖片已經全部加載完成之后才發生的,否則的話,可能會出現圖片只加載了一小半的視圖情況。這又應該如何實現xbn28資訊網——每日最新資訊28at.com

繼續優化。我們希望占位符元素與圖片元素的切換沒那么生硬,而是結合動畫漸入漸出,又該如何實現。xbn28資訊網——每日最新資訊28at.com

繼續優化,我們希望支持傳入 aspectFill 等屬性,確保圖片的縮放比例,不能因為寬高的設置導致圖片比例變形,又該如何實現xbn28資訊網——每日最新資訊28at.com

這些思考就留給大家在實踐中去嘗試驗證了。本文就不在詳細介紹。xbn28資訊網——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-77981-0.html20行代碼,封裝一個 React 圖片懶加載組件

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: Kotlin的擴展(Extension)特性,你了解了嗎?

下一篇: 我們一起解鎖小程序開發新姿勢

標簽:
  • 熱門焦點
Top 主站蜘蛛池模板: 吉安县| 阜康市| 临夏市| 松潘县| 临猗县| 沧源| 青岛市| 金沙县| 万宁市| 新田县| 富裕县| 萝北县| 盐城市| 霍州市| 迭部县| 库伦旗| 泾源县| 武鸣县| 马边| 哈尔滨市| 大邑县| 沿河| 襄垣县| 云霄县| 大渡口区| 顺平县| 涟水县| 娄底市| 肇源县| 塔河县| 大荔县| 新营市| 策勒县| 肇庆市| 上思县| 揭阳市| 宁国市| 金湖县| 合水县| 荣成市| 龙口市|