图片的懒加载

实现思路:

  • 利用浏览器提供的 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 和函数式编程

posted @ 2021-09-15 11:14  一个动态类型的幽灵  阅读(77)  评论(0编辑  收藏  举报