javascript 中实现上拉加载更多需监听滚动并判断触底,当 scrolltop + clientheight >= scrollheight - 50 时发起 fetch 请求,配合 loading 状态防重复,并可用 intersectionobserver 优化性能。

JavaScript 中实现下拉加载更多(即“上拉加载”或“滚动加载”,常被误称为“下拉加载”),核心是监听滚动事件,判断容器底部是否接近可视区域底部,满足条件时发起 Ajax 请求获取新数据并追加到列表中。注意:“下拉加载”通常指下拉刷新(pull-to-refresh),而“加载更多”实际多为上拉触底触发——这里按常见需求理解为滚动到底部自动加载更多。
监听滚动并判断是否触底
关键在于准确检测容器(如 <div id="list">)是否滚动到底部。需对比容器的滚动高度、自身高度和父容器(或窗口)的可视高度:<ul>
<li>
<strong>滚动高度</strong>:<code>element.scrollTop
element.scrollHeight
element.clientHeight
scrollTop + clientHeight >= scrollHeight - 50
用 fetch 或 XMLHttpRequest 发起 Ajax 请求
推荐使用 fetch(现代、简洁),注意处理加载状态避免重复请求:
- 添加
loading标志位,请求开始设为true,结束设为false - 请求成功后解析 JSON,追加数据到 DOM 或更新状态(如 React/Vue 中)
- 失败时给出提示(如 toast),并重置 loading 状态
- 示例片段:
if (!loading && shouldLoadMore()) {<br> loading = true;<br> fetch(`/api/items?page=${page}`)<br> .then(r => r.json())<br> .then(res => {<br> appendList(res.data);<br> if (!res.hasMore) unobserveScroll();<br> page++;<br> loading = false;<br> });<br>}
优化体验:节流、防重复、加载提示
直接绑定 scroll 容易高频触发,需优化:
- 用
setTimeout或requestIdleCallback实现简单节流(如 100ms 内只执行一次) - 在请求中设置
loading = true,阻止连续触发 - 底部添加“加载中…”提示项(可复用一个
<li class="loading">元素,显示/隐藏切换) - 若数据为空或接口返回
hasMore: false,可移除滚动监听或禁用加载逻辑
兼容性与替代方案:Intersection Observer
更现代、性能更好的方式是用 IntersectionObserver 监听底部占位元素是否进入视口:
- 在列表末尾插入一个空的
<div id="loader-trigger"> <li>创建观察器,当该元素出现在视口时触发加载</li> <li>优势:不依赖 scroll 事件,无节流必要,CPU 占用低,尤其适合长列表</li> <li>兼容性:Chrome 51+/Firefox 55+/Safari 12.1+,旧版可用 polyfill</li> </div>











