上拉加载 / 下拉刷新
1. 开源解决方案
社区主流:better-scroll。
使用 better-scroll 实现下拉刷新、上拉加载时要注意以下几点:
- 容器需要固定高度,且需要包含一个内容 wrapper。
- wrapper 高度需大于容器才会产生滚动。
- 滚动方向、阈值、是否启用下拉刷新等通过配置项控制。
- 初始化时机:DOM 渲染完成后调用
new BScroll(el, opts)。
2. 实现原理
上拉加载
触底判断公式:
scrollTop + clientHeight >= scrollHeight
简单实现:
const clientHeight = document.documentElement.clientHeight; // 浏览器高度
const scrollHeight = document.body.scrollHeight;
const scrollTop = document.documentElement.scrollTop;
const distance = 50; // 距视窗底部 50px 时开始触发
if (scrollTop + clientHeight >= scrollHeight - distance) {
console.log('开始加载数据');
}
下拉刷新
下拉刷新的本质是:页面本身置于顶部时,用户下拉时触发的动作。
原生实现主要分为三步:
- 下拉过程:记录手指起点位置、当前下拉距离,显示提示文案(如"下拉刷新")。
- 临界点判断:超过阈值时进入"可释放刷新"状态。
- 松手刷新:用户松手后触发请求,成功后隐藏刷新提示并复位 UI。
下拉到松手的过程会经历三个阶段:
- 下拉中(未到阈值)
- 可释放(到达阈值)
- 刷新中(松手后,发起请求)
补充:现代移动端实现上拉加载 / 下拉刷新时,常配合:
- IntersectionObserver:监听某个 sentinel 元素进入视口,自动触发加载。
- 防抖 / 节流:避免高频滚动事件。
- 虚拟列表:数据量大时避免 DOM 节点过多。
// IntersectionObserver 触底加载示例
const sentinel = document.querySelector('#sentinel');
const io = new IntersectionObserver((entries) => {
if (entries[0].isIntersecting) {
loadMore();
}
});
io.observe(sentinel);
来源整理自:我的有道云笔记



