关于图片懒加载的实现(总结梳理)

前言

	why?
	懒加载:访问一个页面,可视区域的图片优先显示, 而不是一次性加载所有图片,随可视
	区域增加,再发送图片请求,避免打开网页时加载过多资源。使页面加载速度快、减轻
	服务器的压力、节省流量。
	实现方式:
	1、监听页面监听scroll事件滚动(不推荐)
	2、使用:Intersection Observer API
	3、插件vue3-lazy实现(支持vue3和ts)(vue2.x可以使用vue-lazyload)

监听scroll事件

当图片距离视窗顶部的距离大于浏览器窗口显示区的高度时,图片不可见,反之可见
const images = document.querySelectorAll("img");

window.addEventListener("scroll", e => {
  // 先判断每张图片的位置是否在可视区域
  images.forEach(image => {
    const imageTop = image.getBoundingClientRect().top;
    if (imageTop < window.innerHeight) {
      const data_src = image.getAttribute("data-src");
      image.setAttribute("src", data_src);
    }
    console.log("scroll");
  });
});
这种方法会多次触发,不推荐使用,推荐使用下面的IntersectionObserver

使用:Intersection Observer API

当一个IntersectionObserver对象被创建时,其被配置为监听根中一段给定比例的可见区域。
一旦IntersectionObserver被创建,则无法更改其配置,所以一个给定的观察者对象只能用来监听可见区域的特定变化值;
然而,你可以在同一个观察者对象中配置监听多个目标元素。
<template>
  <main class="container">
    <img data-src="/src/assets/images/index/banner.png">
    <img data-src="/src/assets/images/home1/ddstep2.png">
    <img data-src="/src/assets/images/index/banner.png">
    <img data-src="/src/assets/images/index/banner.png">
    <img data-src="/src/assets/images/home1/ddstep2.png">
    <img data-src="/src/assets/images/index/banner.png">
    <img data-src="/src/assets/images/index/banner.png">
    <img data-src="/src/assets/images/home1/ddstep2.png">
    <img data-src="/src/assets/images/index/banner.png">
    <img data-src="/src/assets/images/index/banner.png">
    <img data-src="/src/assets/images/home1/ddstep2.png">
    <img data-src="/src/assets/images/index/banner.png">
    <img data-src="/src/assets/images/index/banner.png">
    <img data-src="/src/assets/images/home1/ddstep2.png">
    <img data-src="/src/assets/images/index/banner.png">
    <img data-src="/src/assets/images/index/banner.png">
    <img data-src="/src/assets/images/home1/ddstep2.png">
    <img data-src="/src/assets/images/index/banner.png">
    <img data-src="/src/assets/images/index/banner.png">
    <img data-src="/src/assets/images/home1/ddstep2.png">
    <img data-src="/src/assets/images/index/banner.png">
    <img data-src="/src/assets/images/index/banner.png">
    <img data-src="/src/assets/images/home1/ddstep2.png">
    <img data-src="/src/assets/images/index/banner.png">
    <img data-src="/src/assets/images/index/banner.png">
    <img data-src="/src/assets/images/home1/ddstep2.png">
    <img data-src="/src/assets/images/index/banner.png">
    <img data-src="/src/assets/images/index/banner.png">
    <img data-src="/src/assets/images/home1/ddstep2.png">
    <img data-src="/src/assets/images/index/banner.png">
  </main>
</template>
<script setup lang="ts">
import { onMounted, ref } from 'vue' // introjs主题

// 传给IntersectionObserver的回调函数
// 在目标元素能看见时触发一次,目标元素看不见了时再触发一次
const observer = new IntersectionObserver((entries) => {
  entries.forEach((entry) => {
    if (entry.isIntersecting) {
      const image = entry.target;
      const data_src:any = image.getAttribute('data-src');
      console.log('src', data_src)
      image.setAttribute('src', data_src);
      // 图片被加载后取消观察
      observer.unobserve(image);
    }
  });
});

onMounted(() => {
  const images = document.querySelectorAll('img');
  images.forEach((image) => {
    observer.observe(image);
  });
})
</script>

<style scoped lang="scss">
  .container{
    font-family: 'Helvetica Neue';
    font-style: normal;
    font-weight: 500;
    font-size: 24px;
    line-height: 32px;
    color: #171B23;
    .header{
      color: #434C5B;
      font-family: 'PingFang SC';
    }
    img{
      width: 200px;
      height: 100px;
    }
  }
</style>

插件 vue3-lazy

安装

npm install vue3-lazy -S

main.ts中全局引入

import { createApp } from 'vue'
import App from './App.vue'
import lazyPlugin from 'vue3-lazy'
createApp(App).use(lazyPlugin,{
  loading: '@/assets/images/default.png',        //图⽚加载中时显⽰的默认图⽚
  error: '@/assets/images/error.png'        //图⽚加载失败后显⽰的图⽚
})

组件使用

<img v-lazy="'/src/assets/images/index/banner.png'">

vue2.x可以参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值