移动端下拉刷新与上拉加载的关键在于滚动行为控制与触底/触顶判定:容器需设明确高度和overflow-y,避免父级截断滚动流;iOS需加-webkit-overflow-scrolling: touch;触底判定应留50px余量,避免精度误差。

移动端实现下拉刷新和上拉加载,关键不在“排版”,而在于容器的滚动行为控制与触底/触顶判定逻辑是否准确。所谓“触底排版”其实是误读——真正影响功能可用性的,是容器能否正确触发 scroll 事件、是否被父级截断滚动流、以及是否适配 iOS 弹性滚动等平台特性。
确保容器可滚动且事件可捕获
很多“触底不触发”问题,根源是容器没真正滚动起来:
- 容器必须有明确高度(如
height: 100vh或固定像素值),且设置overflow-y: auto或scroll;仅靠body滚动时,onReachBottom类机制可能失效 - 避免父元素设置
overflow: hidden或position: fixed意外截断子容器滚动流 - 在 iOS 中,若容器不是
<body>本身,需额外加-webkit-overflow-scrolling: touch启用原生滚动惯性
触底判定要留余量,别依赖“刚好等于”
直接用 scrollTop + clientHeight === scrollHeight 极易失败,因小数精度、缩放、字体渲染差异会导致计算偏差:
- 统一使用“距离底部 ≤ 50px”作为阈值:
scrollHeight - scrollTop - clientHeight - 把判定逻辑放在
scroll事件的节流回调里(如 100ms 一次),避免高频触发重复请求 - 加载中状态要锁定:一旦开始请求,就置
loading = true,直到响应完成才重置,防止快速上拉多次触发
下拉刷新容器需隔离触摸方向,防 iOS 弹性干扰
iOS 的 bounce 效果会让 scrollTop 在顶部短暂变为负值,导致 touchmove 判定失准:
- 只在
scrollTop === 0时才记录touchstart的起始 Y 值 - 在
touchmove中,仅当scrollTop === 0且滑动差值为正时,才允许下拉位移和视觉反馈 - 用
transform: translateY()模拟下拉头,而非修改容器scrollTop,避免与原生滚动冲突
uni-app / 微信小程序等平台要走配置+生命周期
这些平台已封装底层逻辑,硬写 touch 事件反而容易出错:
- 微信小程序:在页面
json中设"enablePullDownRefresh": true,用onPullDownRefresh和wx.stopPullDownRefresh();上拉用onReachBottom,并可在json中调"onReachBottomDistance": 150 - uni-app:同理,在
pages.json配置enablePullDownRefresh和onReachBottomDistance,对应生命周期钩子自动触发 - 切勿在这些平台里再手动监听
touchstart做下拉——会与原生下拉控件打架,出现双动画或卡死


















