左右列表滚动不同步的根本原因是滚动事件未解耦、scroll-top未对齐,且左列表选中逻辑依赖右列表可见区域top值但未节流监听;应同步绑定scroll-top、主动设置leftscrolltop、缓存offsettop、加节流、修正高度基准并确保id静态唯一。

左右双列表滚动不同步,左边选中项不更新
根本原因是两个列表滚动事件没做解耦,scroll-view 的 scroll-top 和 scrollTop 属性没对齐,且 left list 的选中逻辑依赖 right list 当前可见区域的 top 值,但没监听 right list 的 scroll 事件或监听了却没做节流,导致频繁触发、计算错乱。
实操建议:
- 右边
scroll-view必须加:scroll-top.sync="rightScrollTop"(Vue 2)或v-model:scroll-top="rightScrollTop"(Vue 3),并绑定@scroll="onRightScroll" - left list 不要用
scroll-into-view自动滚动,改用this.$nextTick(() => { this.leftScrollTop = targetTop })主动设置,避免和 right 滚动冲突 -
onRightScroll中用event.detail.scrollTop获取实时位置,结合每个分类区块的offsetTop(需在onReady后用uni.createSelectorQuery()预查)判断当前高亮项 - 务必加
throttle(50ms 足够),否则 iOS 下快速滚动会丢帧、误判
分类锚点定位不准,右边滚动后左边高亮错位
常见于使用 uni.createSelectorQuery().select('#cate-' + id).boundingClientRect() 获取 offsetTop 时,节点还没渲染完成,或页面有 sticky header、tabbar 导致计算基准偏移。
实操建议:
- 所有锚点节点(如
<view id="cate-1"></view>)必须加position: relative,避免被父级 transform 影响boundingClientRect结果 - 查询时机:在
onReady后延时setTimeout(() => { queryAllCateHeights() }, 100),比单纯$nextTick更稳妥 - 计算高亮 index 时,用
rightScrollTop + window.innerHeight * 0.3作为“可视区中心线”,而不是直接比对scrollTop,能缓解临界点抖动 - 如果用了
uni-nav-bar或自定义顶部栏,记得从boundingClientRect的top里减去其高度(例如 88rpx → 实际 px 值)
iOS 下 scroll-view 滚动卡顿、联动延迟明显
本质是 scroll-view 在 iOS 上默认开启 bounce 效果,且每次滚动都触发 JS 回调,大量 createSelectorQuery 或 DOM 查询加重主线程压力。
实操建议:
- 右边
scroll-view加属性bounce="false"和show-scrollbar="false",禁用原生回弹和滚动条渲染 - 把所有分类区块的
offsetTop缓存成数组(如this.cateOffsets = [0, 420, 860, ...]),只在初始化查一次,不再滚动中反复查 - left list 的滚动用
scroll-with-animation关闭(设为false),动画由 right 滚动驱动更可控 - 避免在
onRightScroll里调用uni.createSelectorQuery()或修改 data 中大数组,只更新activeCateId和leftScrollTop
TabBar 或下拉刷新干扰滚动计算
当页面启用 enablePullDownRefresh 或底部有 tabBar 时,scroll-view 的实际可滚动高度 ≠ window.innerHeight,且下拉过程会临时改变 scrollTop,导致分类定位跳变。
实操建议:
- 右边
scroll-view的style显式设高度:height: calc(100vh - 100rpx)(100rpx ≈ navBar + tabBar 高度),不要依赖 flex 布局撑开 - 在
onPullDownRefresh里重置rightScrollTop = 0并手动触发一次onRightScroll,保证 left list 同步归位 - 如果用了自定义下拉刷新组件(如
uni-refresh),确保它不包裹整个scroll-view,而是作为scroll-view的第一个子元素,避免影响boundingClientRect计算
最易被忽略的是:右列表每个分类区块的 id 必须唯一且静态(不能是 "cate-"+index 这种依赖渲染顺序的),否则 querySelector 查到的 offsetTop 可能错乱;还有就是真机调试一定要用 Safari Web Inspector 抓 scroll 事件频率,模拟器的滚动行为和真机差异很大。











