這是一個用純函式元件實現的 lazy-load image
LazyLoad.jsx
import React from 'react'
const css = {
box: {
height: '400px',
border: '1px solid pink',
overflowY: 'scroll',
},
imageBox: {
width: '500px',
height: '500px',
margin: '20px auto',
},
}
const images = [] // 要載入的 img 圖片(jsx)
const refs = [] // 圖片的 ref(操作dom時用)
for (let i=0; i<4; i++) { // 新增4張待載入的圖片
const ref = React.createRef() // 新建空 ref
refs.push(ref) // 放入 ref 陣列
images.push( // 新建 img jsx 放入 images (圖片地址不放入 src 而是放入 自定義屬性 data-src)
<div style={css.imageBox} key={i}>
<img ref={ ref } data-src={`https://pschina.github.io/src/assets/images/${i}.jpg`} />
</div>
)
}
const threshold = [0.01] // 這是觸發時機 0.01代表出現 1%的面積出現在可視區觸發一次回掉函式 threshold = [0, 0.25, 0.5, 0.75] 表示分別在0% 25% 50% 75% 時觸發回掉函式
// 利用 IntersectionObserver 監聽元素是否出現在視口
const io = new IntersectionObserver((entries)=>{ // 觀察者
entries.forEach((item)=>{ // entries 是被監聽的元素集合它是一個陣列
if (item.intersectionRatio <= 0 ) return // intersectionRatio 是可見度 如果當前元素不可見就結束該函式。
const {target} = item
target.src = target.dataset.src // 將 h5 自定義屬性賦值給 src (進入可見區則載入圖片)
})
}, {
threshold, // 新增觸發時機陣列
});
// onload 函式
const onload = ()=>{
refs.forEach( (item) => {
io.observe(item.current) // 新增需要被觀察的元素。
} )
}
// 定義懶載入純函式元件
// 為了監聽頁面載入完畢 定義了一個img 利用 onerror 函式替代 onlaod {src需填寫一個不存在圖片的路徑}
const LazyLoadPage = ()=>(
<div style={css.box}>
{images}
<img onError={onload} src="" />
</div>
)
export default LazyLoadPage
複製程式碼
(完)