← 中文资源

简体中文版本

用 IntersectionObserver 实现无限滚动

当哨兵元素进入视口时加载下一页,防止重复请求,并为不滚动的用户保留键盘可用的备用入口。

阅读英文原文

概述

无限滚动能把内存控制在有界范围并保持页面流畅,但必须能抵御快速滚动下的重复请求,也不能成为触达内容的唯一方式。哨兵元素加请求守卫是可靠的核心。

关键步骤

  1. 观察列表下方的哨兵元素,进入视口时触发加载。
  2. 用进行中标志与游标保证并发触发只请求一次。
  3. 追加结果,并在接口不再返回游标时停止观察。
  4. 提供可见的加载更多按钮作为无 JS 与无障碍兜底。

验证

  • 滚动到底部附近时每次只加载一页。
  • 重试后不出现重复条目。
  • 服务端返回无更多页时停止加载。
  • 观察器失效时备用按钮仍可加载。

注意事项

  • 无限滚动不利于深链接与返回原滚动位置,需要页码处应保留分页。
  • 不适合依赖页内查找的长文档。

适用范围

本条目围绕「用 IntersectionObserver 实现无限滚动」给出可复制的步骤、验证方式与常见问题,适合需要按此流程落地的工程团队。执行时请结合自身上下文调整命令与阈值,并在变更前后留存证据,便于后续复核与回滚。

const io = new IntersectionObserver(([e]) => {
  if (e.isIntersecting && !loading && cursor) loadMore(cursor);
});
io.observe(sentinel);
// always render a fallback <button>Load more</button>