结论是:用onpagescroll监听滚动方向+transform: translatey()做位移动画最稳定跨端兼容;因scroll-view的@scroll在app端(尤其ios)常触发不及时、抖动或漏触发,而onpagescroll是官方生命周期钩子,底层调用原生滚动监听,精度高;且scroll-view会阻止onpagescroll触发,混用将导致“有时动有时不动”。

直接说结论:用 onPageScroll 监听滚动方向 + transform: translateY() 做位移动画,是最稳定、跨端兼容性最好的方案。H5、小程序、App 三端都能跑通,不需要额外组件或 touch 事件 hack。
为什么不用 @scroll 或 scroll-view?
因为 scroll-view 的 @scroll 在 App 端(尤其 iOS)经常触发不及时、抖动、甚至漏触发;而页面级 onPageScroll 是 uni-app 官方生命周期钩子,底层调用原生滚动监听,精度和稳定性高得多。
-
scroll-view只适合局部滚动容器,全屏滚动必须用onPageScroll - 如果页面用了
scroll-view包裹内容,onPageScroll就不会触发——这是常见误判点 - 真机调试时发现“有时动有时不动”,八成是混用了
scroll-view和onPageScroll
onPageScroll 怎么判断上滑/下滑?
不能只比大小,得加阈值防误触。比如用户轻微晃动手指,scrollTop 变化 1~2px,不该立刻触发隐藏。
- 记录
lastScrollTop,每次更新前先算差值delta = scrollTop - lastScrollTop - 下滑(隐藏)条件:
delta > 10 && scrollTop > 60(60 是避开顶部操作区的保守值) - 上滑(显示)条件:
delta ,即向上滑动超过 10px 就立刻恢复显示 - 别用
setTimeout延迟判断,会卡顿;动画靠 CSStransition自己完成
自定义导航栏的定位和安全区怎么处理?
如果你用的是 navigationStyle: "custom"(APP/H5 必须这么干),那顶部元素必须手动适配 iPhone X+ 的刘海区。
- 固定定位写法必须带
top: env(safe-area-inset-top),否则在 iOS 上会被状态栏遮住 - 高度不能硬写
88rpx,要用calc(44px + env(safe-area-inset-top))或动态计算 - 隐藏动画用
transform: translateY(-100%),不是top: -100%—— 后者会破坏 fixed 定位流,导致安卓下闪动 - 记得给内容区加
margin-top或padding-top,值等于你的导航栏高度,避免被遮挡
最易被忽略的一点:App 端开启 navigationStyle: "custom" 后,原生导航栏彻底消失,但下拉刷新区域也一并没了。如果需要下拉刷新,必须显式配置 "enablePullDownRefresh": true 并手写 onPullDownRefresh,否则用户下拉毫无反应。











