移动端如何实现下拉滚动加载
移动端实现下拉滚动加载(也叫“上拉加载更多”或“无限滚动”)通常用于列表页,如商品列表、评论等,当用户滚动到页面底部时自动加载下一页数据。下面是常见的实现方式和注意事项:
✅ 一、基本实现原理
1. 监听滚动事件
在滚动区域内监听 scroll 事件,当滚动到底部时触发加载逻辑。
html
<div id="scroll-container" style="height: 500px; overflow-y: auto;">
<ul id="list"></ul>
<div id="loading">加载中...</div>
</div>
js
const container = document.getElementById('scroll-container');
container.addEventListener('scroll', () => {
const { scrollTop, scrollHeight, clientHeight } = container;
if (scrollTop + clientHeight >= scrollHeight - 10) {
// 距底部10px时触发加载
loadMore();
}
});
function loadMore() {
// 加载下一页数据
}
✅ 二、常见优化点
1. 节流/防抖
避免 scroll 高频触发造成性能问题:
js
function throttle(fn, delay) {
let last = 0;
return function (...args) {
const now = Date.now();
if (now - last > delay) {
last = now;
fn(...args);
}
};
}
container.addEventListener('scroll', throttle(handleScroll, 200));
2. 加载锁
防止重复加载:
js
let isLoading = false;
function loadMore() {
if (isLoading) return;
isLoading = true;
showLoading(true);
fetchMoreData().then(() => {
isLoading = false;
showLoading(false);
});
}
3. 分页控制
通过 page 参数控制加载页数,后端配合返回分页数据及是否还有更多:
js
let page = 1;
function fetchMoreData() {
return fetch(`/api/items?page=${page++}`).then(res => res.json()).then(data => {
renderList(data.items);
if (!data.hasMore) {
container.removeEventListener('scroll', handleScroll);
}
});
}
✅ 三、进阶方案:IntersectionObserver
使用 IntersectionObserver 监听“加载更多”元素是否出现在视口中
html
<ul id="list"></ul>
<div id="sentinel">加载中...</div>
js
const sentinel = document.getElementById('sentinel');
const observer = new IntersectionObserver(([entry]) => {
if (entry.isIntersecting) {
loadMore();
}
});
observer.observe(sentinel);
这个方法更高效,适用于 React、Vue、原生开发,且不会频繁触发事件。
✅ 四、移动端适配注意点
- 使用容器 overflow-y: auto 而不是监听 window.scroll,更适配移动端 App/Webview。
- 设置 -webkit-overflow-scrolling: touch 提升滚动流畅性。
- 注意兼容 iOS 上 scroll 事件可能有延迟的问题。
- 如果用 Vue/React,建议封装成组件,如:
vue
<!-- Vue3 示例 -->
<template>
<div ref="scrollRef" @scroll="handleScroll">
<slot></slot>
<div v-if="loading">加载中...</div>
</div>
</template>