如何封装一个懒加载的图片组件

72 阅读2分钟

以下分别是使用原生 JavaScript、Vue 和 React 来封装懒加载图片组件的方法:

原生 JavaScript 实现懒加载图片组件

  • HTML 结构
    创建一个 HTML 文件,在body标签内添加一个div容器,用于包裹图片,并在其中添加img标签,设置data-src属性来存储真实的图片路径,src属性暂时设置为一个占位图片路径或为空字符串。

html

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Image Lazy Load</title>
</head>

<body>
  <div class="image-container">
    <img class="lazy-image" data-src="real-image.jpg" src="placeholder.jpg">
  </div>
  <script src="lazyload.js"></script>
</body>

</html>
  • JavaScript 逻辑
    创建lazyload.js文件,在其中定义懒加载函数。通过IntersectionObserver来监听图片是否进入可视区域,当图片进入可视区域时,将data-src的值赋给src属性,实现图片加载。

javascript

// 获取所有需要懒加载的图片
const lazyImages = document.querySelectorAll('.lazy-image');

// 创建IntersectionObserver实例
const observer = new IntersectionObserver((entries) => {
  entries.forEach((entry) => {
    if (entry.isIntersecting) {
      // 图片进入可视区域,加载真实图片
      const img = entry.target;
      img.src = img.dataset.src;
      // 停止观察该图片
      observer.unobserve(img);
    }
  });
});

// 开始观察每张图片
lazyImages.forEach((img) => {
  observer.observe(img);
});

Vue 实现懒加载图片组件

  • 创建 Vue 组件
    使用 Vue CLI 创建一个 Vue 项目,在src/components目录下创建LazyImage.vue组件。在组件模板中,使用img标签,绑定src属性和data-src属性,通过v-bind指令和v-on指令来处理属性绑定和事件监听。

html

<template>
  <img :src="src" :data-src="dataSrc" @load="onLoad" @error="onError">
</template>

<script>
export default {
  props: {
    dataSrc: {
      type: String,
      required: true
    }
  },
  data() {
    return {
      src: 'placeholder.jpg' // 占位图片路径
    };
  },
  mounted() {
    // 创建IntersectionObserver实例
    const observer = new IntersectionObserver((entries) => {
      entries.forEach((entry) => {
        if (entry.isIntersecting) {
          // 图片进入可视区域,加载真实图片
          this.src = this.dataSrc;
          // 停止观察该图片
          observer.unobserve(this.$el);
        }
      });
    });
    // 开始观察图片
    observer.observe(this.$el);
  },
  methods: {
    onLoad() {
      // 图片加载成功的回调函数
      console.log('Image loaded successfully');
    },
    onError() {
      // 图片加载失败的回调函数
      console.log('Image load failed');
    }
  }
};
</script>

React 实现懒加载图片组件

  • 创建 React 组件
    使用 Create React App 创建一个 React 项目,在src目录下创建LazyImage.js组件。在组件中,使用useStateuseEffect钩子函数来处理状态和副作用。通过IntersectionObserver来监听图片是否进入可视区域,当图片进入可视区域时,更新src状态,加载真实图片。

jsx

import React, { useState, useEffect } from 'react';

const LazyImage = ({ dataSrc }) => {
  const [src, setSrc] = useState('placeholder.jpg'); // 占位图片路径

  useEffect(() => {
    const imgRef = document.createElement('img');
    // 创建IntersectionObserver实例
    const observer = new IntersectionObserver((entries) => {
      entries.forEach((entry) => {
        if (entry.isIntersecting) {
          // 图片进入可视区域,加载真实图片
          setSrc(dataSrc);
          // 停止观察该图片
          observer.unobserve(imgRef);
        }
      });
    });
    // 开始观察图片
    observer.observe(imgRef);

    return () => {
      // 组件卸载时,停止观察
      observer.disconnect();
    };
  }, [dataSrc]);

  const onLoad = () => {
    // 图片加载成功的回调函数
    console.log('Image loaded successfully');
  };

  const onError = () => {
    // 图片加载失败的回调函数
    console.log('Image load failed');
  };

  return <img src={src} data-src={dataSrc} onLoad={onLoad} onError={onError} />;
};

export default LazyImage;