图片懒加载组件
Dennis Zhang
Posted on July 28, 2024
1、主要使用IntersectionObserver API
自定义useIntersectionObserver Hook
import { useEffect, useRef, useState } from 'react';
const useIntersectionObserver = (callback, options) => {
const [entry, setEntry] = useState(null);
const observer = useRef(null);
useEffect(() => {
if (observer.current) observer.current.disconnect();
observer.current = new IntersectionObserver(([entry],_observer) => {
setEntry(entry);
if (entry.isIntersecting) { // 一个布尔值,表示目标元素是否与根元素有交集。
callback(entry); // 设置src加载图片,将观察对象回传callback
_observer.unobserve(entry.target); // 一旦图片加载完成,可以停止观察该元素
}
}, options);
return () => {
if (observer.current) observer.current.disconnect();
};
}, [callback, options]);
return { setTarget: (node) => node && observer.current.observe(node) };
};
创建 LazyImage 组件
import React, { useRef, useState } from 'react';
const LazyImage = ({ src, alt, placeholder }) => {
const [isLoaded, setIsLoaded] = useState(false);
const imgRef = useRef();
const onIntersect = () => {
if (imgRef.current) {
imgRef.current.src = src;
imgRef.current.onload = () => setIsLoaded(true);
}
};
const { setTarget } = useIntersectionObserver(onIntersect, {
root: null, // 使用视口作为根元素
rootMargin: '0px',
threshold: 0.1, // 当至少 10% 的目标元素进入视口时触发回调
});
return (
<div ref={setTarget} style={{ minHeight: '200px', minWidth: '200px' }}>
<img
ref={imgRef}
src={isLoaded ? src : placeholder}
alt={alt}
style={{ opacity: isLoaded ? 1 : 0.5, transition: 'opacity 0.5s' }}
/>
</div>
);
};
export default LazyImage;
使用 LazyImage 组件
import React from 'react';
import LazyImage from './LazyImage';
const App = () => {
return (
<div>
<h1>Lazy Load Images Example</h1>
<LazyImage
src="https://example.com/image.jpg"
alt="Example Image"
placeholder="https://via.placeholder.com/200"
/>
{/* 可以添加更多的 LazyImage 组件 */}
</div>
);
};
export default App;
💖 💪 🙅 🚩
Dennis Zhang
Posted on July 28, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
githubcopilot AI Innovations at Microsoft Ignite 2024 What You Need to Know (Part 2)
November 29, 2024