图片的懒加载
实现思路:
-
利用浏览器提供的
IntersectionObserver
,监听图片元素是否进入可视区域,进入后才真正去设置图片元素的src
属性进行图片加载
IMG 组件js 文件
1 import classnames from 'classnames' 2 import { useEffect, useRef, useState } from 'react' 3 import Icon from '../Icon' 4 import styles from './index.module.scss' 5 6 const Image = ({ className, src, alt }) => { 7 const imgRef = useRef(null) 8 // 控制是否在加载 9 const [loading, setLoading] = useState(true) 10 // 控制是否加载失败 11 const [error, setError] = useState(false) 12 13 // 加载成功 14 const onLoad = () => { 15 setError(false) 16 setLoading(false) 17 } 18 const onError = () => { 19 setLoading(false) 20 setError(true) 21 } 22 useEffect(() => { 23 // 监听图片 24 const observer = new IntersectionObserver(([{ isIntersecting }]) => { 25 if (isIntersecting) { 26 // 图片在可视区 27 imgRef.current.src = imgRef.current.dataset.src 28 // 取消监听 29 observer.unobserve(imgRef.current) 30 } 31 }) 32 observer.observe(imgRef.current) 33 }, []) 34 return ( 35 <div className={classnames(styles.root, className)}> 36 {/* 加载中 */} 37 {loading && ( 38 <div className="image-icon"> 39 <Icon type="iconphoto" /> 40 </div> 41 )} 42 43 {/* 加载出错时显示的内容 */} 44 {error && ( 45 <div className="image-icon"> 46 <Icon type="iconphoto-fail" /> 47 </div> 48 )} 49 50 <img 51 alt={alt} 52 ref={imgRef} 53 data-src={src} 54 onLoad={onLoad} 55 onError={onError} 56 /> 57 </div> 58 ) 59 } 60 61 export default Image
IMG 组件scss文件
1 .root { 2 position: relative; 3 display: inline-block; 4 width: 100%; 5 height: 100%; 6 :global { 7 img { 8 display: block; 9 width: 100%; 10 height: 100%; 11 } 12 13 .image-icon { 14 position: absolute; 15 left: 0; 16 top: 0; 17 display: flex; 18 justify-content: center; 19 align-items: center; 20 width: 100%; 21 height: 100%; 22 background-color: #f7f8fa; 23 } 24 25 .icon { 26 color: #dcdee0; 27 font-size: 32px; 28 } 29 } 30 }
使用方法 :
将js文件和css文件放入components组件中
在需要用到图片懒加载的页面中 导入IMG组件 替换img标签就可以使用 前提是使用hooks 和函数式编程