onpagescroll比bindscroll更稳定,需关闭disablescroll;ios真机需开启enhanced:true;android低端机应节流回调;视差位移须限幅防负值;导航栏响应依赖scrolltop分段判断,避免transition冲突。

onPageScroll 比 bindscroll 更稳,但必须关掉 disableScroll
商品详情页整个页面滚动,用 onPageScroll 拿 scrollTop 是最直接的方式。它不依赖 scroll-view 嵌套,避免安卓 WebView 下 scroll-view 高度塌陷、iOS 事件延迟抖动等问题。
关键前提是:在 pages.json 对应页面配置里,确认没写 "disableScroll": true;如果写了,onPageScroll 根本不会触发。
- 真机调试时 iOS 必须开
enhanced: true(H5 和小程序不用) - Android 低端机容易丢帧,建议用节流函数控制回调频率,比如
throttle(fn, 30) - 别在 onPageScroll 里直接改
transform,先存值,this.$nextTick或 requestAnimationFrame 再更新样式
视差位移不能硬乘系数,得限幅+防负值
常见错误是写 transform: translateY(${scrollTop * 0.5}px)——一滑就飘、回弹抽搐,因为没约束范围,也没处理 scrollTop 为负或超大时的异常。
正确做法是把位移映射到一个合理区间,比如头图最多上移 80px,且不随滚动无限上升:
- 用
Math.min(scrollTop * 0.3, 80)控制最大偏移量 - 加
Math.max(..., 0)防止负值导致元素反向错位 - 缩放/透明度同理:缩放别超过 1.2,透明度别低于 0.3,否则视觉断裂
- 安卓闪屏要加
transform: translateZ(0) will-change: transform
导航栏分层响应靠 scrollTop 分段判断,不是 CSS 动画
淘宝式导航栏不是靠 CSS 过渡自动变化,而是根据 scrollTop 数值分段控制各元素状态——搜索框、分类入口、Logo 各自独立响应,互不干扰。
例如:
if (scrollTop
- 阈值别写死,建议用
uni.getSystemInfoSync().windowHeight * 0.15动态算基准值 - 别用
transition控制导航栏变化,容易和滚动冲突卡顿;用transform+opacity更稳 - 注意真机下
scrollTop可能为小数,做比较时别用严格相等(===),用 >= /
滚动联动吸顶和 tab 高亮必须用元素真实 offsetTop
页面滚动时让导航栏吸顶、顶部 tab 随内容区块高亮,不能只靠 scrollTop 硬匹配固定像素值——不同设备、不同字号下区块高度会变,必须取 DOM 实际位置。
做法是:用 uni.createSelectorQuery() 提前查出每个区块的 top 值,缓存进 data,再在 onPageScroll 里比对:
- 吸顶临界点 = 第二个区块的
top- 导航栏高度 - tab 高亮逻辑:遍历所有区块
top,找最后一个top 的索引 - 别在每次
onPageScroll里重复查 DOM,查一次缓存即可 - H5 端要注意
offsetTop受父级定位影响,建议统一用boundingClientRect()
复杂点不在滚动本身,而在如何让视差、吸顶、tab 高亮三者共享同一套 scrollTop 数据源,又互不干扰更新节奏——节流、缓存、限幅,缺一不可。











