以下分别是使用原生 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组件。在组件中,使用useState和useEffect钩子函数来处理状态和副作用。通过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;