通过交叉实现数据触底分页效果new IntersectionObserver()(html、react、vue2、vue3)中使用

ops/2024/12/28 11:22:07/

react中用法 

import React, { useState, useEffect, useRef } from 'react';const InfiniteScroll = () => {const [items, setItems] = useState([]);const [loading, setLoading] = useState(false);const [page, setPage] = useState(1);const loaderRef = useRef(null);// 模拟加载更多数据的函数const loadMoreData = () => {if (loading) return; // 防止重复加载setLoading(true);// 模拟异步数据请求setTimeout(() => {const newItems = Array.from({ length: 10 }, (_, index) => `Item ${(page - 1) * 10 + index + 1}`);setItems((prevItems) => [...prevItems, ...newItems]);setPage((prevPage) => prevPage + 1);setLoading(false);}, 1000); // 模拟请求延时};useEffect(() => {// 创建 IntersectionObserverconst observer = new IntersectionObserver(([entry]) => {if (entry.isIntersecting) {loadMoreData(); // 当加载元素进入视口时,触发加载更多数据}},{rootMargin: '0px', // 可根据需要调整,决定何时触发threshold: 1.0, // 触发条件:元素完全进入视口});// 启动观察if (loaderRef.current) {observer.observe(loaderRef.current);}// 清理 observerreturn () => {if (loaderRef.current) {observer.unobserve(loaderRef.current);}};}, [loading, page]);return (<div><div>{items.map((item, index) => (<div key={index}>{item}</div>))}</div>{/* 触底加载元素 */}<div ref={loaderRef}>{loading ? <p>Loading...</p> : <p>Scroll down to load more...</p>}</div></div>);
};export default InfiniteScroll;

原生js中用法 

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Infinite Scroll with IntersectionObserver</title><style>body {font-family: Arial, sans-serif;padding: 0;margin: 0;height: 2000px; /* Just to make the page scrollable */}.item {padding: 10px;margin: 10px 0;background-color: #f4f4f4;border: 1px solid #ddd;}#loading {text-align: center;padding: 10px;background-color: #f1f1f1;}</style>
</head>
<body><div id="content"><!-- 初始内容 --><div class="item">Item 1</div><div class="item">Item 2</div><div class="item">Item 3</div><div class="item">Item 4</div><div class="item">Item 5</div></div><!-- 加载更多的提示 --><div id="loading">Loading more...</div><script>// 模拟加载更多数据的函数let page = 1;const loadMoreData = () => {// 模拟异步请求数据setTimeout(() => {const content = document.getElementById('content');for (let i = 0; i < 5; i++) {const newItem = document.createElement('div');newItem.classList.add('item');newItem.textContent = `Item ${page * 5 + i + 1}`;content.appendChild(newItem);}page++;}, 1000); // 模拟1秒的延迟};// 设置 IntersectionObserver 监听“加载更多”元素const loadingElement = document.getElementById('loading');const observer = new IntersectionObserver((entries, observer) => {// 只在元素完全进入视口时触发entries.forEach(entry => {if (entry.isIntersecting) {loadMoreData();observer.unobserve(loadingElement); // 停止监听当前元素observer.observe(loadingElement); // 重新开始监听}});}, {rootMargin: '0px',threshold: 1.0 // 完全进入视口时触发});// 启动 IntersectionObserverobserver.observe(loadingElement);</script>
</body>
</html>

Vue2中使用

<template><div><!-- 内容部分 --><div class="content"><div v-for="(item, index) in items" :key="index" class="item">{{ item }}</div></div><!-- 加载更多提示 --><div id="loading" class="loading">加载更多...</div></div>
</template><script>
export default {data() {return {items: ['Item 1', 'Item 2', 'Item 3'], // 初始数据page: 1, // 当前页数};},mounted() {// 设置 IntersectionObserver 监听加载更多区域const loadingElement = document.getElementById('loading');const observer = new IntersectionObserver(this.handleIntersection, {rootMargin: '0px',threshold: 1.0, // 完全进入视口时触发});observer.observe(loadingElement);},methods: {handleIntersection(entries, observer) {entries.forEach((entry) => {if (entry.isIntersecting) {// 如果加载更多区域进入视口,加载更多数据this.loadMoreData();}});},loadMoreData() {setTimeout(() => {const newItems = Array.from({ length: 5 }, (_, i) => `Item ${this.page * 5 + i + 1}`);this.items.push(...newItems); // 添加新数据this.page += 1; // 增加页码}, 1000); // 模拟网络请求延时},},
};
</script><style>
.content {height: 1500px; /* 让页面滚动 */
}.item {padding: 10px;margin: 10px 0;background-color: #f4f4f4;border: 1px solid #ddd;
}.loading {text-align: center;padding: 10px;background-color: #f1f1f1;
}
</style>

Vue3中使用

<template><div><!-- 内容部分 --><div class="content"><div v-for="(item, index) in items" :key="index" class="item">{{ item }}</div></div><!-- 加载更多提示 --><div id="loading" class="loading">加载更多...</div></div>
</template><script>
import { ref, onMounted } from 'vue';export default {setup() {const items = ref(['Item 1', 'Item 2', 'Item 3']); // 初始数据const page = ref(1); // 当前页数// 加载更多数据的函数const loadMoreData = () => {setTimeout(() => {const newItems = Array.from({ length: 5 }, (_, i) => `Item ${page.value * 5 + i + 1}`);items.value.push(...newItems); // 添加新数据page.value += 1; // 增加页码}, 1000); // 模拟网络请求延时};// 处理 IntersectionObserver 逻辑const handleIntersection = (entries, observer) => {entries.forEach((entry) => {if (entry.isIntersecting) {loadMoreData(); // 如果加载更多区域进入视口,加载更多数据}});};// 在组件挂载时设置 IntersectionObserveronMounted(() => {const loadingElement = document.getElementById('loading');const observer = new IntersectionObserver(handleIntersection, {rootMargin: '0px',threshold: 1.0,});observer.observe(loadingElement);});return { items };},
};
</script><style>
.content {height: 1500px; /* 让页面滚动 */
}.item {padding: 10px;margin: 10px 0;background-color: #f4f4f4;border: 1px solid #ddd;
}.loading {text-align: center;padding: 10px;background-color: #f1f1f1;
}
</style>


http://www.ppmy.cn/ops/145640.html

相关文章

FreeType矢量字符库的介绍、交叉编译以及安装

FreeType矢量字符库的介绍 FreeType 是一个开源的跨平台字体引擎库&#xff0c;广泛用于 Linux 嵌入式系统中实现字符显示的功能。它提供了高效的 TrueType、OpenType 和其他字体格式的解析和渲染功能&#xff0c;在嵌入式开发中尤其适合用来绘制矢量字体和位图字体。 FreeTy…

全面Kafka监控方案:从配置到指标

文章目录 1.1.监控配置1.2.监控工具1.3.性能指标系统相关指标GC相关指标JVM相关指标Topic相关指标Broker相关指标 1.4.性能指标说明1.5.重要指标说明 1.1.监控配置 开启JMX服务端口&#xff1a;kafka基本分为broker、producer、consumer三个子项&#xff0c;每一项的启动都需要…

`we_chat_union_id IS NOT NULL` 和 `we_chat_union_id != ‘‘` 这两个条件之间的区别

文章目录 1、什么是空字符串&#xff1f;2、两个引号之间加上空格 好的&#xff0c;我们来详细解释一下 we_chat_union_id IS NOT NULL 和 we_chat_union_id ! 这两个条件之间的区别&#xff0c;以及它们在 SQL 查询中的作用&#xff1a; 1. we_chat_union_id IS NOT NULL 含…

计算机的错误计算(一百九十三)

摘要 用两个大模型化简计算 其中有关数字取弧度&#xff0c;结果保留5位有效数字。一个大模型进行了一次化简&#xff0c;另外一个大模型没有化简。两个大模型​​​​​均给出错误结果。 例1. 化简计算 其中有关数字取弧度&#xff0c;结果保留5位有效数字。 下面是与一个…

es6 字符串每隔几个中间插入一个逗号

const insertCommaEveryNChars (str, n) > {// 将字符串转换为数组&#xff0c;以便我们可以更容易地操作每个字符const chars str.split();// 使用map遍历数组&#xff0c;并在每隔n个字符后插入逗号const result chars.map((char, index) > {// 检查当前位置是否是n…

网络安全等级自我评价

大家查看之后觉得有意义及帮助记得关注加点赞&#xff01;&#xff01;&#xff01; 很多人觉得网络安全很模糊&#xff0c;很多从事网络安全的同僚&#xff0c;觉得网络安全很杂、自己也不知道自己到底处在哪一阶层&#xff0c;我通过百度、行业了解整理、专业人士的沟通和探…

4-Gin HTML 模板渲染 --[Gin 框架入门精讲与实战案例]

HTML 模板渲染 下面是使用 Gin 框架在 Go 语言中进行 HTML 模板渲染的四个示例。每个示例都包含了必要的注释来解释代码的作用。 示例1&#xff1a;基本模板渲染 package mainimport ("github.com/gin-gonic/gin""net/http" )func main() {r : gin.Defa…

CUDA基础编程:开启深度学习 GPU 加速之门

文章结尾有最新热度的文章,感兴趣的可以去看看。 本文是经过严格查阅相关权威文献和资料,形成的专业的可靠的内容。全文数据都有据可依,可回溯。特别申明:数据和资料已获得授权。本文内容,不涉及任何偏颇观点,用中立态度客观事实描述事情本身 文章有点长(字),期望您能坚…