当前位置: 首页 > article >正文

34、如何实现上拉加载,下拉刷新?

这是前端面试里很常见的实战题。它考察的不只是 API 会不会用更重要的是你是否理解滚动原理触底判断移动端触摸事件请求节流与状态控制用户体验优化分页 / 数据管理性能和边界处理如果你能按这些点来回答面试官会觉得你不只是“会写”而是真的做过。一、先说概念1上拉加载上拉加载本质上是当用户滚动到底部附近时自动请求下一页数据并追加到列表末尾。常用于商品列表文章列表评论区消息流瀑布流2下拉刷新下拉刷新本质上是当用户在列表顶部继续向下拖动时触发数据重新加载一般是重新请求第一页数据并替换当前列表。常用于新闻流社交 Feed聊天列表移动端 App WebView 页面二、面试中推荐先说实现思路你可以先总述一句上拉加载核心是“触底检测 分页请求 列表追加 防重复请求”下拉刷新核心是“顶部检测 下拉距离判断 刷新请求 列表重置”。这一句非常适合开头面试官会觉得你有结构。三、上拉加载怎么实现上拉加载通常有两种主流实现方式scroll 事件监听IntersectionObserver 监听底部哨兵元素方案一基于 scroll 事件实现这是最传统、最常见的方式。核心原理监听页面滚动当满足“滚动到底部附近”时触发加载下一页。常见判断条件scrollTop clientHeight scrollHeight - threshold含义scrollTop当前滚动距离clientHeight可视区域高度scrollHeight内容总高度threshold提前量比如 50px、100px示例代码let page 1 let loading false let finished false async function loadMore() { if (loading || finished) return loading true const res await fetch(/api/list?page${page}) const data await res.json() if (data.list.length 0) { finished true } else { renderList(data.list) page } loading false } window.addEventListener(scroll, () { const scrollTop document.documentElement.scrollTop || document.body.scrollTop const clientHeight document.documentElement.clientHeight const scrollHeight document.documentElement.scrollHeight if (scrollTop clientHeight scrollHeight - 100) { loadMore() } })面试加分点一定要主动提这几个状态loading防止重复请求finished避免没有更多数据后继续请求page分页控制threshold提前触发优化体验方案二基于 IntersectionObserver 实现这是更现代、更推荐的方式。思路在列表底部放一个“哨兵元素”sentinel当这个元素进入视口时就说明用户快滚动到底部了然后触发加载更多。示例ul idlist/ul div idloadMoreTrigger/divconst trigger document.getElementById(loadMoreTrigger) const observer new IntersectionObserver((entries) { if (entries[0].isIntersecting) { loadMore() } }, { root: null, threshold: 0.1 }) observer.observe(trigger)优点不需要频繁监听 scroll性能更好代码更简洁更适合懒加载、无限滚动面试加分说法如果浏览器环境允许我会优先考虑IntersectionObserver因为它比手动监听 scroll 更优雅也更利于性能优化。这句话很加分。四、下拉刷新怎么实现下拉刷新更常见于移动端。它通常依赖当前滚动位置是否在顶部触摸开始位置触摸移动距离是否超过触发阈值松手时执行刷新核心流程用户触摸开始记录起始位置如果当前页面滚动已经在顶部再向下拉计算下拉距离超过阈值后显示“松开刷新”触摸结束时执行刷新逻辑请求第一页数据并重置列表简化示例let startY 0 let distance 0 let isRefreshing false const container document.getElementById(container) container.addEventListener(touchstart, (e) { if (document.documentElement.scrollTop 0) { startY e.touches[0].clientY } }) container.addEventListener(touchmove, (e) { const currentY e.touches[0].clientY distance currentY - startY if (distance 0 document.documentElement.scrollTop 0) { // 更新下拉提示 UI console.log(下拉距离, distance) } }) container.addEventListener(touchend, async () { if (distance 80 !isRefreshing) { isRefreshing true await refreshList() isRefreshing false } distance 0 })刷新逻辑下拉刷新通常不是“追加数据”而是“重置数据”async function refreshList() { const res await fetch(/api/list?page1) const data await res.json() resetList(data.list) page 2 finished false }五、如果是 PC 端下拉刷新怎么理解严格来说原生“下拉刷新”更偏移动端交互。在 PC 端通常不会真的做“手势下拉”而是用点击刷新按钮顶部刷新提示条滚动回顶部自动刷新定时刷新如果面试官问的是通用 Web 页面你可以回答下拉刷新更多是移动端场景PC 端通常不会完全模拟触摸下拉而是用其他交互形式替代。这个回答会显得你有产品和场景意识。六、实际项目中要注意哪些问题这一部分是“精彩回答”的关键。1防止重复请求上拉加载和下拉刷新都要有状态位控制if (loading) return否则快速滚动、快速拖动会触发多次请求。2处理“没有更多数据”后端通常会返回总条数total是否还有下一页hasMore当前页page前端要根据这些信息决定是否继续加载。3节流 / 防抖如果是scroll监听实现上拉加载需要做节流function throttle(fn, delay) { let timer null return function (...args) { if (timer) return timer setTimeout(() { fn.apply(this, args) timer null }, delay) } }window.addEventListener(scroll, throttle(checkLoadMore, 200))为什么因为 scroll 事件触发非常频繁不节流会影响性能。4避免请求竞态问题如果用户触发多次刷新或切换很快可能导致后返回的旧请求覆盖新数据。解决方式请求取消AbortController请求序号比对只认最新请求结果这个点说出来会很加分。5用户体验优化比如正在加载时显示 loading没有更多数据显示“到底了”下拉中显示“下拉刷新 / 松开刷新”刷新完成后显示“刷新成功”这些细节体现工程和产品意识。6回弹效果与阻止默认行为移动端下拉刷新 often 需要处理页面原生回弹浏览器默认下拉刷新行为touchmove 时是否preventDefault这个点在 H5 中尤其常见。不过要注意某些浏览器原生下拉刷新不容易完全禁用需要结合具体容器和 CSS如overflow设计7列表过长时做虚拟列表如果上拉加载导致列表越来越长DOM 节点过多会造成卡顿。这时候可以结合虚拟滚动分片渲染图片懒加载这个点是高级加分项。七、面试中怎么回答更精彩你可以这样组织语言标准版回答上拉加载和下拉刷新本质上都是列表场景中的数据增量更新方案。上拉加载的核心是监听滚动位置在接近底部时触发下一页请求把新数据追加到列表末尾下拉刷新的核心是在列表顶部时监听用户向下拖动的手势超过一定阈值后触发刷新请求第一页数据并重置列表。上拉加载实现上传统做法是监听scroll事件通过scrollTop clientHeight scrollHeight - threshold来判断是否触底更现代的方案是用IntersectionObserver监听底部哨兵元素进入视口这样性能更好。下拉刷新一般更多用于移动端通常结合touchstart、touchmove、touchend来计算下拉距离在顶部下拉超过阈值后触发刷新。实际开发中我会特别关注几个问题第一增加loading状态防止重复请求第二根据hasMore或总页数控制是否继续加载第三scroll监听要做节流第四要处理请求竞态、加载提示和空状态如果列表很长还会考虑虚拟列表来避免 DOM 过多导致卡顿。这已经是比较完整、成熟的回答了。八、如果想回答得更高级可以补这一段在实际项目中如果是普通 Web 列表我会优先使用IntersectionObserver实现上拉加载因为它比频繁监听scroll更优雅、性能也更好如果是移动端 H5 下拉刷新我会结合顶部容器和 touch 事件做自定义手势处理同时注意和浏览器原生回弹行为的兼容。此外请求层我一般会增加去重、取消、错误重试和分页状态管理避免因为网络抖动造成重复加载或数据错乱。这段非常有项目味道。九、常见面试追问1上拉加载为什么要节流因为scroll事件触发频率很高如果每次都执行复杂逻辑或发请求会带来性能问题。2如何判断是否到底部常见公式scrollTop clientHeight scrollHeight - threshold3为什么IntersectionObserver更好减少手动监听 scroll浏览器底层优化更好代码更简洁适合懒加载和无限滚动4下拉刷新为什么主要用于移动端因为它依赖手势交互移动端触摸下拉更自然PC 端通常不会用这种交互方式。5如果连续触发加载怎么办通过loading状态锁、防抖/节流、请求取消等方式避免重复请求。6如果请求回来顺序乱了怎么办可以给请求加唯一标识只处理最后一次请求使用AbortController取消旧请求十、精简版面试回答如果面试时间不多你可以这样说上拉加载的核心是触底检测当用户滚动到底部附近时请求下一页数据并追加到列表中下拉刷新的核心是在列表顶部监听用户向下拖动超过阈值后重新请求第一页数据并重置列表。上拉加载通常可以通过scroll事件判断scrollTop clientHeight scrollHeight - threshold来实现也可以用IntersectionObserver监听底部哨兵元素这种方式性能更好。下拉刷新更多用于移动端通常结合touchstart、touchmove、touchend来实现。实际开发中我会重点处理loading防重复请求、hasMore控制是否还有下一页、scroll 节流、请求竞态、以及 loading / empty / finished 等状态展示。十一、一句话总结面试官真正想听的是你是否理解上拉加载和下拉刷新的核心原理你是否知道scroll 方案和 IntersectionObserver 方案你是否知道移动端 touch 事件实现下拉刷新你是否具备分页、状态控制、性能优化、异常处理这些工程意识

相关文章:

34、如何实现上拉加载,下拉刷新?

这是前端面试里很常见的实战题。 它考察的不只是 API 会不会用,更重要的是你是否理解:滚动原理触底判断移动端触摸事件请求节流与状态控制用户体验优化分页 / 数据管理性能和边界处理如果你能按这些点来回答,面试官会觉得你不只是“会写”&am…...

Kuikly实现Android iOS Web小程序一码覆盖实践

跨端开发趋势与“一码覆盖”的现实路径 在多终端普及与用户场景碎片化的背景下,移动、桌面、Web与小程序的并行发展让“一次开发、多端运行”成为开发者的核心诉求。传统方案中,React Native因桥接机制存在通信延迟与UI不一致问题,Flutter因…...

数码管字符对照表

...

ESP居然能当 DNS 服务器用?内含NCSI欺骗和DNS劫持实现妆

前言 Kubernetes 本身并不复杂,是我们把它搞复杂的。无论是刻意为之还是那种虽然出于好意却将优雅的原语堆砌成 鲁布戈德堡机械 的狂热。平台最初提供的 ReplicaSets、Services、ConfigMaps,这些基础组件简单直接,甚至显得有些枯燥。但后来我…...

.Acwing基础课第题-简单-区间和纲

在AI辅助开发的语境下,Skill就是一个包含了领域知识、最佳实践、代码模板的知识包。 以"DAO层CRUD生成"为例,一个Skill包含: /mnt/skills/dao-crud/ ├── SKILL.md # 使用说明 │ ├── 何时使用这个Skill │ …...

GCC优化禁用指南:精准控制编译行为的5种方法

1. 为什么需要禁用GCC优化? 在嵌入式开发或者调试过程中,我们经常会遇到一些奇怪的bug:明明代码逻辑没有问题,但程序运行时却出现异常。这时候很可能就是编译器优化在"捣鬼"。GCC作为最常用的开源编译器,它的…...

AI FUTURE北京亦庄AI未来大会在京启幕

4月8日,AI FUTURE北京亦庄AI未来大会在北京经济技术开发区(简称“北京经开区”,又称“北京亦庄”)北京智慧电竞赛事中心正式启幕。这场为期两天的人工智能盛会,以“让每个人看AI的另一面”为主题,集高端论坛…...

Java实战:通过URL调用自动化触发DolphinScheduler工作流

1. 为什么需要自动化触发工作流? 想象一下你负责一个电商平台的订单处理系统。每当用户下单时,系统需要自动触发一系列操作:库存扣减、支付状态更新、物流信息生成...如果每次都手动点击"运行"按钮,不仅效率低下&#…...

ATCODER ABC C题解炼

这&#xff0c;是一个采用C精灵库编写的程序&#xff0c;它画了一幅漂亮的图形&#xff1a; 复制代码 #include "sprites.h" //包含C精灵库 Sprite turtle; //建立角色叫turtle void draw(int d){for(int i0;i<5;i)turtle.fd(d).left(72); } int main(){ …...

第7章 序列凸近似(SCA)与迭代优化

7.1 凸近似理论基础 7.1.1 一阶泰勒近似与SCA框架构建 7.1.2 序列二次约束二次规划&#xff08;SQCQP&#xff09;精炼 7.1.3 分数规划&#xff08;Fractional Programming&#xff09;与Dinkelbach变换 7.2 联合收发波形-滤波器设计 7.2.1 交替迭代优化&#…...

代码审计 | Log4j2 —— CVE-2021-44228 JNDI 注入与递归解析的完整链路分析

代码审计 | Log4j2 —— CVE-2021-44228 JNDI 注入与递归解析的完整链路分析 目录 环境搭建 漏洞复现 编写测试代码 构造恶意 class 文件 启动 LDAP 转发器 请求流程 使用 JNDI 工具一键利用 代码审计 payload 入口追踪 MessagePatternConverter:关键转折点 substitu…...

嵌入式轻量级RPC实现:裸机与RTOS下的远程过程调用

1. RPCInterface 库深度解析&#xff1a;嵌入式系统远程过程调用的轻量级实现RPC&#xff08;Remote Procedure Call&#xff0c;远程过程调用&#xff09;在嵌入式系统中长期被视为“高不可攀”的技术——常与大型操作系统、复杂网络栈和资源消耗挂钩。然而&#xff0c;在工业…...

第6章 黎曼流形优化与几何方法

第6章 黎曼流形优化与几何方法 6.1 黎曼几何基础 6.1.1 复Stiefel流形与单位模流形&#xff08;Unit-Modulus Manifold&#xff09;度量 6.1.2 指数映射&#xff08;Exponential Mapping&#xff09;与平行移动&#xff08;Parallel Transport&#xff09; 6.1.3 测…...

筑牢代码安全基石:GB/T 34943/34944 标准详解与库博静态分析工具的全面支持

一、标准概述&#xff1a;GB/T 34943 与 GB/T 34944 国家标准在软件安全日益成为国家信息化战略核心的背景下&#xff0c;GB/T 34943-2017《C/C 语言源代码漏洞测试规范》与 GB/T 34944-2017《Java 语言源代码漏洞测试规范》两项国家标准应运而生国家标准化管理委员会。由全国信…...

53、竞态条件和同步---------多线程、竟态条件和同步

竞态条件和同步线程是程序执行的最小单位&#xff0c;一个进程可以包含多个线程&#xff0c;多个线程共享进程的资源&#xff08;如内存空间&#xff09;。在多线程环境中&#xff0c;线程之间的并发执行可能导致对共享资源的竞争。 竞态条件&#xff08;Race Condition&#x…...

避坑指南:当你的bed文件在hg38分析中报错时,可能缺了这步liftover预处理

基因组坐标转换实战&#xff1a;当hg38遇到旧版bed文件的高阶解决方案 临床数据分析师小张最近遇到了一个棘手问题——团队传承下来的hg19版bed文件在新项目中使用hg38参考基因组时频繁报错。GATK流程抛出"Invalid interval"警告&#xff0c;IGV可视化时靶向区域完全…...

搞卫星导航数据分析?别光看表格了!用MATLAB把天空图(Skyplot)和多路径效应画出来

卫星导航数据分析实战&#xff1a;用MATLAB绘制天空图与多路径效应可视化 当你在处理GNSS观测数据时&#xff0c;那些密密麻麻的数字表格是否让你感到无从下手&#xff1f;作为一名长期与卫星导航数据打交道的工程师&#xff0c;我深知直接阅读原始数据的痛苦。今天&#xff0c…...

从零到一:用Poste.io和Docker打造你的专属邮件服务器,告别第三方服务限制

从零到一&#xff1a;用Poste.io和Docker打造你的专属邮件服务器&#xff0c;告别第三方服务限制 在数字化通信日益重要的今天&#xff0c;拥有一个完全自主控制的邮件服务器不仅是技术能力的体现&#xff0c;更是数据主权的重要保障。想象一下&#xff0c;当你的每一封邮件都经…...

AI时代新型的项目管理应该是什么样的?商

AI训练存储选型的演进路线 第一阶段&#xff1a;单机直连时代 早期的深度学习数据集较小&#xff0c;模型训练通常在单台服务器或单张GPU卡上完成。此时直接将数据存储在训练机器的本地NVMe SSD/HDD上。 其优势在于IO延迟最低&#xff0c;吞吐量极高&#xff0c;也就是“数据离…...

为什么你的C# 13主构造函数反而变慢了?揭秘字段初始化顺序、属性注入与依赖解析的致命时序冲突

第一章&#xff1a;为什么你的C# 13主构造函数反而变慢了&#xff1f;C# 13 引入的主构造函数&#xff08;Primary Constructors&#xff09;本意是简化类型初始化语法&#xff0c;但实际性能表现可能与直觉相悖——在某些场景下&#xff0c;它反而比传统构造函数更慢。根本原因…...

开源项目 Agentic OS 实战指南:手把手教你从 ANOLISA 源码安装

首个面向 Agent 的操作系统——Agentic OS发布后&#xff0c;收到许多询问&#xff0c;是否能在本地部署&#xff1f;当然可以&#xff0c;Agentic OS 已经在 GitHub 上开源&#xff0c;开源项目是「ANOLISA」。 本文会详细介绍如何准备开发环境、从源码构建 ANOLISA 各组件并…...

Figma+Cursor联动实战:5分钟搞定AI设计稿生成(含最新manifest导入避坑指南)

FigmaCursor联动实战&#xff1a;5分钟搞定AI设计稿生成&#xff08;含最新manifest导入避坑指南&#xff09; 在快节奏的前端开发领域&#xff0c;设计稿与代码的同步效率往往成为项目瓶颈。传统工作流中&#xff0c;设计师产出视觉稿后&#xff0c;开发者需要手动还原每个像素…...

坐标系工艺参数的设定

在一台专机机床上模拟圆弧程序时&#xff0c;发现G2和G3的方向是反的&#xff0c;G2轴按逆时针方向运行&#xff0c;G3轴按顺时针方向运行。测试程序如下&#xff1a;G19G0 G90 Y0 Z0G2 Y100 Z100 CR100 F500M30G2指令时&#xff0c;圆弧为逆时针方向G3指令时&#xff0c;圆弧为…...

别再死记硬背AXI时序了!用Vivado Block Design搭个玩具,看波形秒懂握手协议

从零玩转AXI协议&#xff1a;用Vivado图形化工具破解握手时序之谜 第一次接触AXI协议时&#xff0c;那些密密麻麻的时序图让我头皮发麻——AWVALID、AWREADY、WLAST...这些信号就像天书一样难以理解。直到有一天&#xff0c;我决定抛开枯燥的文档&#xff0c;直接在Vivado里动手…...

Flutter The Dart VM Service was not discovered after 60 seconds.

更新系统配置好 Flutter 环境报错&#xff1a; The Dart VM Service was not discovered after 60 seconds. This is taking much longer than expected... Open the Xcode window the project is opened in to ensure the app is running. If the app is not running, try …...

IC Hack Badge嵌入式驱动开发:LED扫描与FreeRTOS多任务实战

1. IC Hack Badge 嵌入式驱动开发深度解析 IC Hack Badge 是为 2025 年 IC Hack 硬件黑客马拉松定制的开源 PCB 电子徽章&#xff0c;其核心价值不仅在于物理形态的趣味性&#xff0c;更在于其作为嵌入式底层开发教学与实战平台的工程意义。该徽章采用主流低成本 MCU 架构&…...

VS Code开发STM32:高效嵌入式开发环境搭建指南

1. 为什么选择VS Code开发STM32&#xff1f; 作为一名嵌入式开发工程师&#xff0c;我最初接触STM32开发时使用的也是Keil MDK。但随着项目复杂度提升&#xff0c;Keil的局限性逐渐显现&#xff1a;收费高昂&#xff08;虽然可以找到特殊版本&#xff09;、代码补全功能弱、界…...

ICLR 2026两篇满分思路:不规则时间序列+条件扩散模型,研一就能复现!

时序生成式预测在金融与医疗等高风险领域至关重要。面对数据非平稳性、极端事件冲击及采样不规则等严峻挑战&#xff0c;传统点预测常因过度自信而失效&#xff0c;产生巨大风险。本文解析的两项最新研究开辟了新路径&#xff1a;前者首创不确定性门控&#xff08;Uncertainty-…...

LangChain4j vs Spring AI:Java开发者选型指南(含DeepSeek接入对比)

LangChain4j vs Spring AI&#xff1a;Java开发者选型指南&#xff08;含DeepSeek接入对比&#xff09; 当Java开发者面临在项目中集成大语言模型&#xff08;LLM&#xff09;的需求时&#xff0c;框架选择往往成为第一个技术决策点。LangChain4j和Spring AI作为当前Java生态中…...

告别ArcGIS!用GEE+QGIS搞定流域DEM下载与地形分析(附完整代码)

告别ArcGIS&#xff01;用GEEQGIS搞定流域DEM下载与地形分析&#xff08;附完整代码&#xff09; 在GIS领域&#xff0c;数字高程模型&#xff08;DEM&#xff09;是地形分析的基础数据。传统上&#xff0c;ArcGIS凭借其完善的功能和稳定的性能&#xff0c;成为DEM处理的首选工…...