【前端】IntersectionObserver 实现图片懒加载和无限滚动

【前端】IntersectionObserver 实现图片懒加载和无限滚动

在前端开发中,性能优化是一个重要的考量因素。随着现代网页和应用的复杂性增加,确保页面快速加载和流畅运行变得越来越重要。本文将介绍一种强大的工具——IntersectionObserver API,并结合 Vue 项目,讲解如何使用它来实现图片懒加载和无限滚动。
在这里插入图片描述

IntersectionObserver API 简介

IntersectionObserver API 是现代浏览器提供的一种异步观察者,它可以监视一个元素与视口(或某个特定祖先元素)交叉状态的变化。它的主要用途包括:

  • 图片懒加载
  • 无限滚动加载内容
  • 实现元素的延迟加载
  • 触发动画效果

IntersectionObserver 的基本用法

要使用 IntersectionObserver,首先需要创建一个 IntersectionObserver 实例,并传入一个回调函数和一些配置选项:

const observer = new IntersectionObserver(callback, options);
  • callback: 每当被观察的元素的可见性变化时,调用的回调函数。该函数接收两个参数:
    • entries: 被观察元素的列表,每个元素都是一个 IntersectionObserverEntry 对象。
    • observer: IntersectionObserver 实例本身。
  • options: 一个可选参数对象,用于配置观察器的行为。包括以下属性:
    • root: 用于观察的祖先元素,默认为视口。
    • rootMargin: 根元素的外边距,用于扩大或缩小根元素的判定区域。
    • threshold: 一个数组,规定在什么可见比例下触发回调。

回调函数

回调函数处理 IntersectionObserverEntry 对象的数组,每个对象包含了元素的交叉信息:

const callback = (entries, observer) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      // 元素进入视口
      console.log('Element is in viewport:', entry.target);
      // 执行懒加载操作,如加载图片
      const img = entry.target;
      img.src = img.dataset.src;
      // 停止观察当前元素
      observer.unobserve(entry.target);
    }
  });
};

配置选项示例

const options = {
  root: null, // 默认为视口
  rootMargin: '0px', // 没有外边距
  threshold: 0.1 // 当 10% 的目标元素可见时触发回调
};

观察目标元素

创建 IntersectionObserver 实例后,可以使用 observe 方法来观察目标元素:

const img = document.querySelector('img');
observer.observe(img);

完整示例

以下是一个完整的示例,展示如何使用 IntersectionObserver 实现图片懒加载:

document.addEventListener('DOMContentLoaded', () => {
  const images = document.querySelectorAll('img[data-src]');

  const callback = (entries, observer) => {
    entries.forEach(entry => {
      if (entry.isIntersecting) {
        const img = entry.target;
        img.src = img.dataset.src;
        observer.unobserve(img);
      }
    });
  };

  const options = {
    root: null,
    rootMargin: '0px',
    threshold: 0.1
  };

  const observer = new IntersectionObserver(callback, options);

  images.forEach(image => {
    observer.observe(image);
  });
});

更加深入的学习我推荐:阮一峰的帖子

在 Vue 项目中实现图片懒加载

接下来,我们将结合 Vue 项目,使用 IntersectionObserver 实现图片懒加载。首先,我们需要创建一个自定义指令 v-lazy

创建自定义指令

在 Vue 中,我们可以通过自定义指令来实现懒加载。以下是一个简单的实现:

Vue.directive('lazy', {
  inserted: function(el, binding) {
    let observer;
    if (IntersectionObserver) {
      observer = new IntersectionObserver(entries => {
        entries.forEach(entry => {
          if (entry.isIntersecting) {
            observer.unobserve(el);
            const src = binding.value;
            el.src = src;
          }
        });
      });
      observer.observe(el);
    } else {
      // 如果浏览器不支持 IntersectionObserver,需要提供一个降级方案
      el.src = binding.value;
    }
  }
});

在模板中使用指令

<template>
  <div>
    <img v-lazy="imageSource" alt="Lazy loaded image" />
  </div>
</template>

<script>
export default {
  data() {
    return {
      imageSource: 'path/to/image.jpg'
    };
  }
};
</script>

这样,当图片进入视口时,v-lazy 指令会触发加载图片,从而实现懒加载。

在 Vue 项目中实现无限滚动

除了图片懒加载,我们还可以使用 IntersectionObserver 实现无限滚动加载内容。以下是实现步骤:

创建无限滚动组件

Vue.component('infinite-scroll', {
  data() {
    return {
      items: [],
      page: 1,
      observer: null,
    };
  },
  mounted() {
    this.loadItems();
    this.createObserver();
  },
  methods: {
    loadItems() {
      // 模拟加载数据
      fetch(`https://api.example.com/items?page=${this.page}`)
        .then(response => response.json())
        .then(data => {
          this.items = [...this.items, ...data];
          this.page += 1;
        });
    },
    createObserver() {
      const options = {
        root: null,
        rootMargin: '0px',
        threshold: 1.0
      };

      this.observer = new IntersectionObserver((entries, observer) => {
        entries.forEach(entry => {
          if (entry.isIntersecting) {
            this.loadItems();
          }
        });
      }, options);

      this.$nextTick(() => {
        const sentinel = this.$refs.sentinel;
        this.observer.observe(sentinel);
      });
    }
  },
  template: `
    <div>
      <div v-for="item in items" :key="item.id" class="item">
        {{ item.name }}
      </div>
      <div ref="sentinel" class="sentinel"></div>
    </div>
  `
});

在主应用中使用组件

<template>
  <div id="app">
    <infinite-scroll></infinite-scroll>
  </div>
</template>

<script>
import InfiniteScroll from './components/InfiniteScroll.vue';

export default {
  components: {
    InfiniteScroll
  }
};
</script>

在这个示例中,当用户滚动到页面底部时,IntersectionObserver 会触发回调函数,加载更多数据并更新页面内容,从而实现无限滚动。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/770843.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

智胜未来:AI如何重塑SaaS用户增长战略

在当今这个数字化时代&#xff0c;SaaS&#xff08;软件即服务&#xff09;已成为企业运营的重要支柱&#xff0c;而人工智能&#xff08;AI&#xff09;技术的迅猛发展&#xff0c;正以前所未有的方式重塑着SaaS行业的面貌&#xff0c;特别是对其用户增长战略产生了深远影响。…

每日一题——Python实现PAT乙级1005 继续(3n+1)猜想(举一反三+思想解读+逐步优化)五千字好文

一个认为一切根源都是“自己不够强”的INTJ 个人主页&#xff1a;用哲学编程-CSDN博客专栏&#xff1a;每日一题——举一反三Python编程学习Python内置函数 Python-3.12.0文档解读 目录 我的写法 代码逻辑概述 时间复杂度分析 空间复杂度分析 总结 我要更强 代码优化点…

Openwrt路由器部分ipv6公网地址无法访问的问题

路由器是Openwrt&#xff0c;终端访问ipv6地址经常有些能访问&#xff0c;有些不能访问&#xff0c;一开始以为是运营商问题&#xff0c;后面ssh到openwrt发现所有访问都正常。 查阅资料后才知道是MTU设置问题&#xff0c;Openwrt 默认MTU是1492&#xff0c;使用IPV6应减少60个…

Word文档中公式的常用操作

一、参考资料 二、常用操作 插入公式 Alt 多行公式 Shift Enter 多行公式对齐 WORD Tips: 多行公式编辑及对齐 word自带公式等号对齐&#xff08;可任意符号处对齐&#xff09; 多行公式按照 为基准对齐。 拖动鼠标选中整个公式点击右键&#xff0c;选择【对齐点(…

[激光原理与应用-97]:激光焊接焊中检测系统系列介绍 - 1 - 什么是焊接以及传统的焊接方法

目录 一、什么是焊接 1.1 概述 1.2 基本原理 二、传统的焊接技术与方法 2.1 手工电弧焊&#xff1a; 1、定义与原理 2、特点 3、焊条类型 4、应用领域 5、安全注意事项 2.2 气体保护焊&#xff1a; 1、原理与特点 2、应用领域 3、气体选择 4、注意事项 2.3 电阻…

C++ 文达校内党员管理系统-计算机毕业设计源码20855

目 录 摘要 1 绪论 1.1研究背景与意义 1.2国内外研究现状 1.3论文结构与章节安排 2 文达校内党员管理系统系统分析 2.1 可行性分析 2.2 系统功能分析 2.2.1 功能性分析 2.2.2 非功能性分析 2.3 系统用例分析 2.4 系统流程分析 2.4.1 数据流程 2.5.2 业务流程 2.…

CPU/内存/综合性能评估工具汇总-3:unixbench

目录 一、概括二、UnixBench 一、概括 嵌入式开发中对要设计的产品、立项的项目进行设计时&#xff0c;往往需要对关键芯片进行性能评估&#xff0c;本文主要总结基于linux系统的产品在性能评估时的工具使用总结&#xff0c;在aarch64(arm64平台下测试)&#xff0c;板卡根文件…

前端学习(三)CSS介绍及选择符

##最近在忙期末考试&#xff0c;因此前端笔记的梳理并未及时更新。在学习语言过程中&#xff0c;笔记的梳理对于知识的加深very vital.因此坚持在明天学习新知识前将笔记梳理完整。 主要内容&#xff1a;CSS介绍及选择符 最后更新时间&#xff1a;2024/7/4 目录 内容&#x…

Redis 7.x 系列【15】持久化机制之 RDB

有道无术&#xff0c;术尚可求&#xff0c;有术无道&#xff0c;止于术。 本系列Redis 版本 7.2.5 源码地址&#xff1a;https://gitee.com/pearl-organization/study-redis-demo 文章目录 1. 概述2 执行原理3. 配置项3.1 save3.2 stop-writes-on-bgsave-error3.3 rdbcompress…

HMI 的 UI 风格创造奇迹

HMI 的 UI 风格创造奇迹

关于巴图自动化Profinet协议转Modbus协议网关模块怎么配置IP地址教学

Profinet协议和Modbus协议是工业领域中常用的两种通讯协议&#xff0c;除此以外还有较为常见的&#xff1a;ModbusTCP协议&#xff0c;Profibus协议&#xff0c;Profibus DP协议&#xff0c;EtherCAT协议&#xff0c;EtherNET协议&#xff0c;CAN&#xff0c;CANOPEN等它们在自…

利用运放设计简单有源滤波器(低通、高通、带通)

本文旨在帮助刚接触模电的同学快速设计一个实用可靠的有源滤波器&#xff0c;故我将不会说一些晦涩难懂的原理&#xff0c;只给出仿真电路图。 低通滤波器 图1 低通滤波器 图1所示的是一个截止频率约为1KHz的低通滤波器。 图2 200Hz的情况 图3 2KHz的情况 设计步骤为&#x…

Lesson 47 A cup of coffee

Lesson 47 A cup of coffee 词汇 like v. 喜欢&#xff0c;想要 用法&#xff1a;like 物品 / 人 喜欢……    like 动词ing 喜欢做……&#xff08;习惯性&#xff09;    like to 动词原形 喜欢做……&#xff08;一次性&#xff09; 例句&#xff1a;我喜欢小狗…

一、强化学习基本概念

一、强化学习基本概念 1.1 何为强化学习&#xff1f;1.2 强化学习的环境1.3 强化学习的目标1.4 强化学习的数据 1.1 何为强化学习&#xff1f; 强化学习(Reinforcement Learning, RL)是机器通过与环境交互来实现目标的一种计算方法。机器和环境的一轮交互是指&#xff1a;机器在…

FlinkCDC-3.1.1 DataStream Source

问题&#xff1a; Caused by: java.lang.ClassNotFoundException: org.apache.flink.table.catalog.ObjectPath 解决&#xff1a; 在poml文件中&#xff0c;导入的flink-table依赖把“ <scope>”去掉 <properties><maven.compiler.source>8</maven.compi…

安卓稳定性之crash详解

目录 前言一、Crash 的基本原理二、Crash 分析思路三、实例分析四、预防措施五、参考链接 前言 在开发和测试 Android 应用程序时&#xff0c;遇到应用程序崩溃是很常见的情况。 Android 崩溃指的是应用程序因为异常或错误而无法正常执行&#xff0c;并且导致应用强制关闭。 一…

通过一个单相逆变器仿真深度学习PR控制器

目录 前言 ​编辑 PR控制器的理论 PR控制器不同表达式及其建模 PR控制器连续积分组合及模型 PR控制器连续传递函数及模型 PR控制器离散积分及模型 PR控制器离散传递函数及模型 PR控制器差分方程及模型 系统仿真效果 总结 前言 在项目开发中常用PI控制器&#xff0c;这次在…

java实现【 生成小程序二维码:图片+二维码备注】

1.逻辑&#xff1a;进行获取小程序的token进行-获取不限制的小程序码。2.参考的地址&#xff1a;微信官方文档&#xff1a;官网-获取不限制的小程序码 需要注意的点&#xff1a;1. 如果传入page这个参数的话必须定义check_path参数&#xff0c;不然无法识别-page指定的目录2. …

2024微信小程序期末大作业-点奶茶微信小程序(后端nodejs-server)(附下载链接)_微信小程序期末大作业百度网盘下载

菜单展示 购物车展示&#xff1a; 提交订单&#xff1a; 支付详情页展示&#xff1a; 订单查看&#xff1a; 查看历史消费&#xff1a; 部分代码展示&#xff1a; <!--pages/home/home.wxml--> <block wx:for"{{listData}}" wx:key"itemlist&qu…

国标GB28181视频汇聚平台LntonCVS视频监控安防平台与国标协议对接解决方案

应急管理部门以“以信息化推动应急管理能力现代化”为总体目标&#xff0c;加快现代信息技术与应急管理业务深度融合&#xff0c;全面支持现代应急管理体系建设&#xff0c;这不仅是国家加强和改进应急管理工作的关键举措&#xff0c;也是应对日益严峻的应急管理形势和满足公众…