intersectionobserver实现触底加载的核心是监听末尾占位元素进入视口(哪怕1px),配合rootmargin提前触发、isloading防重复请求、unobserve/observe动态管理及空数据/错误的三层终止逻辑。

监听滚动到底部的时机不等于 window.onscroll 直接绑定
直接在 window 上监听 scroll 事件,容易高频触发、卡顿,且“到底部”的判断逻辑常出错。关键不是滚动本身,而是容器可视区域与内容末尾的距离关系。
推荐用 IntersectionObserver 替代手动计算 scrollTop + scrollHeight:它更轻量、不阻塞主线程,且天然支持懒加载语义。
- 观察目标设为页面最后一个列表项(如
<li class="item" data-id="123">),而非整个容器 - 当该元素进入视口(哪怕只露出 1px),就触发加载,避免“差一点没触底”的体验断层
- 加载中需临时取消观察(
unobserve),防止重复请求;新数据插入后,重新observe最后一项
fetch 请求失败或空数据时,必须显式终止后续加载
无限滚动最常被忽略的是“终点”信号——后端返回空数组、has_more: false 或 HTTP 404,不代表前端能自动停。若不拦截,用户会持续下拉、白屏、控制台报错。
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
实际处理要分三层判断:
- 网络失败(
fetch抛异常):重试最多 1 次,之后提示“加载失败”,并保留“点击重试”按钮 - 响应成功但数据为空(
response.data.length === 0):置hasMore = false,移除观察者,不再监听 - 响应含
next_cursor或page字段但值为null/"":同上,视为数据终结
DOM 插入方式影响滚动锚定和性能
把新 <li> 直接 append() 到列表末尾,看似简单,但会导致两个问题:一是 iOS Safari 滚动位置突变(尤其键盘弹起后);二是大量节点插入引发强制同步布局(Layout Thrashing)。
- 用
DocumentFragment批量构建新节点,再一次性appendChild,减少重排次数 - 插入前记录当前滚动高度(
container.scrollTop),插入后立即恢复,避免视觉跳动 - 对长列表(>500 条),考虑配合
virtual list(如react-window原理),但纯 HTML 场景建议加“回到顶部”按钮+节流渲染
移动端 touchmove 事件干扰导致“假触底”
在 iOS 和部分安卓 WebView 中,快速滑动后惯性滚动可能触发 IntersectionObserver 多次回调,或 touchmove 未正确取消默认行为,造成误加载。
- 给滚动容器添加
touch-action: pan-y,禁用横向拖拽干扰 - 确保容器有明确高度(如
max-height: 70vh)和overflow-y: auto,避免body滚动导致 observer 失效 - 在
observer回调中加防抖:用setTimeout延迟 100ms 再执行加载,过滤掉瞬时多次触发
IntersectionObserver 的兼容性(IE 不支持)和空数据兜底,才是上线前最容易漏掉的两处。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










