实现图片懒加载的几种方式

通过element plus实现图片懒加载

非常简单,只需要使用标签,然后写上lazy属性即可!!!

<style scoped>
    .img-box {
        text-align: center;
    }
    .lazyImg {
        width: 500px;
        height: 500px;
        margin: 2rem;
    }
</style>
<template>
<ul class="img-box">
    <li v-for="item in resData" :key="item.id">
        <el-image :src="item.url" lazy fit="cover" class="lazyImg" alt=""></el-image>
    </li>
</ul>
</template>
<script setup type="ts">
    import {reactive} from 'vue'
    const resData = reactive([
        {id: '1', url: 'https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg'},
        {id: '2', url: 'https://fuss10.elemecdn.com/a/3f/3302e58f9a181d2509f3dc0fa68b0jpeg.jpeg'},
        {id: '3', url: 'https://fuss10.elemecdn.com/1/34/19aa98b1fcb2781c4fba33d850549jpeg.jpeg'},
        {id: '4', url: 'https://fuss10.elemecdn.com/0/6f/e35ff375812e6b0020b6b4e8f9583jpeg.jpeg'},
        {id: '5', url: 'https://fuss10.elemecdn.com/9/bb/e27858e973f5d7d3904835f46abbdjpeg.jpeg'},
    ]);
</script>

原生JS实现

原理:
图片还未出现到浏览器窗口可视画面,就不加载图片,当窗口滚动到图片出现位置,才加载

方法一:监听scroll事件,鼠标滚动触发,计算高度

  1. 窗口可视高度:window.innerHeight
  2. 图片到视窗顶部的距离:dom.getBoundingClientRect().top
  3. 计算"2" - "1"的距离,大于0,则还未出现不需要加载,反之加载
// 获取全部的img标签
const images = document.querySelectorAll('img');

// 监听窗口滚动事件
window.addEventListener('scroll', (e) => {
    // 窗口可视高度
    const height = window.innerHeight;
    // 判断图片是否出现在窗口可视化区域
    images.forEach(image => {
        // 图片到窗口顶部的距离
        const top = image.getBoundingClientRect().top;
        if (top < height) {// 可见 -> 开始加载(将data-src的值赋值给src)
            const url = image.getAttribute('data-src');
            image.setAttribute('src', url);
        }
    });
});

方法二:使用IntersectionObserve(交叉观察)

  1. intersectionObserve目标元素和可视区域产生的交叉区域,是浏览器提供的构造函数,需要浏览器支持
  2. 创建一个实例const observer = new IntersectionObserver(callback);
  3. callback回调函数会触发两次(1.目标出现触发一次,2.目标消失触发一次)
  4. 观察节点:observe(DOM节点)
  5. 取消观察:unobserve(DOM节点),图片加载出来后就不需要观察了
// 获取全部的img标签
const images = document.querySelectorAll('img');

// 创建交叉观察实例
const observer = new IntersectionObserver(entries => {
    entries.forEach(entry => {
        // entry.target目标元素
        const image = entry.target;
        const url = image.getAttribute('data-src');
        // 是否交叉entry.isIntersecting
        if (entry.isIntersecting) {
            image.setAttribute('src', url);
            // 出现加载后,取消观察
            observer.unobserve(image);
        }
    });
});

// 遍历image标签,通过observer实例观察每个dom
images.forEach(image => {
    observer.observe(image);
});

开箱即用的完整demo

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <style>
        p {text-align:center;}
        img {width: 1280px;height: 760px;margin: 2rem;}
    </style>
    <title>图片懒加载</title>
</head>
<body>
    <p>我爱学习</p>
    <p>学习使我快乐</p>
    <p>我爱编程</p>
    <p>编程使我快乐</p>
    <p>==============================</p>
    <p>我爱学习</p>
    <p>学习使我快乐</p>
    <p>我爱编程</p>
    <p>编程使我快乐</p>
    <p>==============================</p>
    <p>我爱学习</p>
    <p>学习使我快乐</p>
    <p>我爱编程</p>
    <p>编程使我快乐</p>
    <p>==============================</p>
    <p>我爱学习</p>
    <p>学习使我快乐</p>
    <p>我爱编程</p>
    <p>编程使我快乐</p>
    <p>==============================</p>
    <img data-src="https://fuss10.elemecdn.com/1/34/19aa98b1fcb2781c4fba33d850549jpeg.jpeg" alt="">
    <img data-src="https://fuss10.elemecdn.com/9/bb/e27858e973f5d7d3904835f46abbdjpeg.jpeg" alt="">
    <img data-src="https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg" alt="">

    <script>
	const images = document.querySelectorAll('img');
	const observer = new IntersectionObserver(entries => {
	    entries.forEach(entry => {
	        const image = entry.target;
	        const url = image.getAttribute('data-src');
	        if (entry.isIntersecting) {
	            image.setAttribute('src', url);
	            observer.unobserve(image);
	        }
	    });
	});
	images.forEach(image => {
	    observer.observe(image);
	});
	</script>
</body>
</html>

使用vue-lazyload库实现

安装

# 安装指令
$ npm i vue-lazyload -S
# cdn 引人<script src="https://unpkg.com/vue-lazyload/vue-lazyload.js"></script>

main.ts中引入

import VueLazyload from 'vue-lazyload'
Vue.use(VueLazyload)

简单使用

<!-- vue中 -->
<template>
	<ul>
        <li v-for="img in list">
            <img v-lazy="img.src" alt="">
        </li>
    </ul>
</template>

<!-- html中 -->
<div v-lazy-container="{ selector: 'img' }">
  <img data-src="//domain.com/img1.jpg">
  <img data-src="//domain.com/img2.jpg">
  <img data-src="//domain.com/img3.jpg">  
</div>

详细介绍:https://www.npmjs.com/package/vue-lazyload

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值