【前端】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 会触发回调函数,加载更多数据并更新页面内容,从而实现无限滚动。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

golang 自旋

自旋 自旋锁的定义&#xff1a;当一个线程尝试去获取某一把锁的时候&#xff0c;如果这个锁此时已经被别人获取(占用)&#xff0c;那么此线程就无法获取到这把锁&#xff0c;该线程将会等待&#xff0c;间隔一段时间后会再次尝试获取。这种采用循环加锁 -> 等待的机制被称为…

力扣2488.统计中位数为 K 的子数组

力扣2488.统计中位数为 K 的子数组 等价转换 子数组为奇数 &#xff1a; 左小 右小 左大 右大 左小 – 左大 右大 – 右小 子数组为偶数 &#xff1a; 左小 右小 左大 右大 – 1 左小 – 左大 右大 – 右小 - 1提示中说明k为两数中左边那个 先从k的下标pos开始往左逆序…

LabVIEW新能源汽车电池性能测试系统

新能源汽车的核心部件之一是电池&#xff0c;其性能直接关系到整车的续航里程、安全性和寿命。为了确保电池的性能和可靠性&#xff0c;测试是必不可少的环节。本文介绍了一种基于LabVIEW的新能源汽车电池性能测试系统&#xff0c;通过LabVIEW与数据采集设备的无缝集成&#xf…

Unity 实现UGUI 简单拖拽吸附

获取鼠标当前点击的UI if(RectTransformUtility.RectangleContainsScreenPoint(rectTransform, Input.mousePosition)) {return rectTransform.gameObject; } 拖拽 在Update 中根据鼠标位置实时更新拖拽的图片位置。 itemDrag.transform.position Input.mousePosition; …

秒拿AI模型API Key!Chat2DB AI模型切换实用秘籍

智谱AI&#xff08;ZhiPu AI&#xff09; 智谱 AI 是由清华大学计算机系技术成果转化而来的公司&#xff0c;致力于打造新一代认知智能通用模型。 1.申请调用权限 智谱AI开放平台网址&#xff1a;https://open.bigmodel.cn/ 点击开始使用&#xff0c;进行登录/注册。 智谱A…

The Sandbox 创作者的幕后采访: 了解创作者的内心世界

我们采访了一些在 "创作者挑战" 中脱颖而出的顶尖创作者&#xff0c;探讨他们成功的秘诀以及在创造玩家喜爱的体验方面的心得。 The Sandbox 创作者挑战涌现出许多才华横溢的创作者&#xff0c;他们在游戏制作机制上的创新和突破引起了 The Sandbox 社区的广泛关注。…

大白菜U盘启动工具

大白菜如何u盘启动进winpe装系统大白菜是一款非常实用的U盘启动盘制作工具&#xff0c;可以帮助用户快速地将U盘制作成启动盘&#xff0c;从而方便地进行系统安装、维护和修复等操作。官方网站&#xff1a; 大白菜u盘启动盘制作工具_大白菜u盘装系统_大白菜pe_大白菜官网-首页…

为什么缠中说禅要选择08年“假死”跑路?

在缠中说禅的信徒圈内&#xff0c;流传着创始人李彪于2008年逝世的说法&#xff0c;这一事件常被描绘成一种悲壮的牺牲&#xff0c;仿佛是为了其理念与信徒们的福祉鞠躬尽瘁。然而&#xff0c;这一“逝世”既未经公开证实&#xff0c;也与李彪生前构建的高大名声形成了某种讽刺…

Spring AI 1.0.0 新变化,从 0.8.1 如何升级

Spring AI 1.0.0-M1 版本已经发布&#xff0c;距离 1.0.0 正式版又更近了一步。同时这也意味着&#xff0c;Spring AI 1.0.0 的 API 已经基本确定&#xff0c;不会发生大的改动。这里介绍一下&#xff0c;相对于上一个发布版本 0.8.1&#xff0c;Spring AI 1.0.0 的一些重要的变…

轻松跨越国界:使用WildCard畅享全球AI服务

大家好&#xff0c;现在AI技术已经深入到我们的日常生活中。然而&#xff0c;许多朋友仍然难以获取优质的AI工具和应用。那么&#xff0c;如何才能使用像ChatGPT这样的AI服务呢&#xff1f; 今天我为大家介绍一个“一劳永逸”的解决方案&#xff0c;它就是我们的主角——WildC…

HDU 1506 Largest Rectangle in a Histogram (DP或单调栈+笛卡尔树)

传送门 题目大意&#xff1a; 有N条的长条状的矩形&#xff0c;宽度都为1&#xff0c;第i条高度为Hi&#xff0c;相邻的竖立在x轴上&#xff0c;求最大的子矩形面积 DP思路及代码 求出当前点能够到达的最左边和最右边的位置&#xff0c;答案就是&#xff08;最右边-最左边&…

阿里云 ECS 服务器的安全组设置

阿里云 ECS 服务器的安全组设置 缘由安全组多个安全组各司其职一些常见的IP段百度 IP 段华为云 IP 段搜狗蜘蛛 IP 段阿里云 IP 段 。。。 缘由 最近公司规模缩减&#xff0c;原有的托管在 IDC 机房的服务器&#xff0c;都被处理掉了&#xff0c;所有代码都迁移到了阿里云的云服…

大模型学习笔记2【大模型】

文章目录 学习内容1.选择基座模型2.验证3.微调4.训练数据5.Instruction Tuning6.训练7.测试8.部署 学习内容 介绍流程 1.选择基座模型 基座模型对结果比较重要&#xff0c;一般选择的流程&#xff1a;首先关注整体性能&#xff08;打榜&#xff09;&#xff0c;其次关注所需…

腾讯云函数部署环境[使用函数URL]

使用函数URL 之前使用的是网关API,最近腾讯云的网关API说要关闭了,所以没有办法这里改成函数URL,使用后发现只要不是在浏览器直接访问的情况,函数URL都可以满足! 这里结合腾讯云函数node.js返回自动带反斜杠这篇文章来做说明,比如这里的URL如下: 结合文章腾讯云函数node.js返…

数组与 ArrayList 的区别是什么?

在Java中&#xff0c;数组和ArrayList都是非常常见的数据结构&#xff0c;但它们在使用场景、特点和功能上各有千秋。 理解它们的不同&#xff0c;对于初级Java工程师来说&#xff0c;是提升编程技能的一个重要环节。 下面&#xff0c;我将以一种简单明了的方式&#xff0c;对…

T113基于评估板SDK配置PD引脚异常

使用PD0/PD1/PD2作为IO输入时,发现输入检测到的值异常,断开输入的信号,直接示波器打IO口,还能发现波形信号,猜测该引脚存在引脚复用情况。 原因 这三个引脚在默认系统是作为显示相关引脚功能。 解决方法 1 ) Uboot修改

99. 岛屿数量

题目描述&#xff1a;给定一个由 1&#xff08;陆地&#xff09;和 0&#xff08;水&#xff09;组成的矩阵&#xff0c;你需要计算岛屿的数量。岛屿由水平方向或垂直方向上相邻的陆地连接而成&#xff0c;并且四周都是水域。你可以假设矩阵外均被水包围。 输入描述&#xff1a…

SSZipArchive 解压后 中文文件名乱码问题

不知道什么情况&#xff0c;做为一个三方广泛使用的框架库&#xff0c;会出现这种比较低级的问题&#xff01; 还有中文的文件名解压后显示乱码&#xff01; 经过深入研究排查&#xff0c;发现目录或文件名编码错误&#xff01;但是POD库&#xff0c;不可能直接在里面改&#…

评估指标rouge安装与测试

github链接 https://github.com/pltrdy/rougegit clone https://github.com/pltrdy/rouge cd rouge python setup.py install新建一个py文件进行测试 注意:不能命名为rouge,否则导入相同的模块会因重名而报错!测试1(文本测试)from rouge import Rouge hypothesis = "…

Objective-C语法基础

注&#xff1a;编译器版本 XCode 15.4 新建一个XCode项目 新建一个类 1、成员变量、属性 1.1、类内使用成员变量&#xff0c;类外使用属性 Role.h #import <Foundation/Foundation.h>NS_ASSUME_NONNULL_BEGINinterface Role : NSObject {//成员变量&#xff1a;只能…