在uni-app中,通过onpagescroll监听scrolltop变化实现底部栏显隐:记录上一次scrolltop,对比当前值,超过阈值(如10px)且向下滑动并超过200px时隐藏,反之显示;需禁用custom导航栏、避免scroll-view包裹全页,并确保app端启用原生渲染。

uni-app 中如何用 onPageScroll 监听滚动并控制底部栏显隐
直接用 onPageScroll 拿不到精确的滚动方向和速度,但能拿到 scrollTop,足够做“滑动阈值判断”。关键不是实时响应,而是防抖 + 方向记忆:记录上一次 scrollTop,对比当前值,大于阈值才触发隐藏/显示。
- 必须在页面级(
pages.json里不能设navigationStyle: custom,否则onPageScroll不触发) -
onPageScroll在 H5 和小程序表现一致,但 App 端需开启原生渲染(vue.config.js配置uni-app的usingComponents为 true)才稳定 - 别用
scroll-view套整个页面——它会拦截原生滚动事件,导致onPageScroll不触发 - 示例逻辑:
data() { return { lastScrollTop: 0, isBottomBarHidden: false } },<br>onPageScroll(e) {<br> const { scrollTop } = e;<br> const delta = scrollTop - this.lastScrollTop;<br> if (Math.abs(delta) > 10) { // 防误触<br> if (delta > 0 && scrollTop > 200) { // 向下滑且已滚过一定距离<br> this.isBottomBarHidden = true;<br> } else if (delta this.isBottomBarHidden = false;<br> }<br> }<br> this.lastScrollTop = scrollTop;<br>}
底部栏用 transform: translateY() 实现平滑动画而非 v-show
v-show 是 display 切换,没有过渡;要动画必须用 transform 或 top + transition。uni-app 的 view 组件支持 CSS 过渡,但需注意:iOS 下 transform 在 fixed 元素上有渲染 bug,建议加 will-change: transform 强制硬件加速。
- 样式写法:
.bottom-bar {<br> position: fixed;<br> bottom: 0;<br> left: 0;<br> right: 0;<br> transition: transform 0.3s cubic-bezier(0.22, 0.61, 0.36, 1);<br> will-change: transform;<br>}<br>.bottom-bar.hidden {<br> transform: translateY(100%);<br>} - 不要用
opacity配合visibility——用户仍可点击穿透 - App 端若出现动画卡顿,检查是否启用了
renderjs或webview渲染模式;推荐用native渲染(HBuilderX 3.7+ 默认)
手势结束时的“回弹”逻辑怎么加
单纯靠 onPageScroll 无法感知手指抬起瞬间,所以得结合 touchstart / touchend 补充判断:如果滑动距离短、速度慢,就恢复显示;否则保持隐藏。这个“回弹”其实是用户体验补丁,不是必须,但知乎做了。
播客文章生成器。将音频文字稿、节目链接、摘要笔记转化为结构清晰、适合发布的图文文章。支持多种输出风格(深度解析、精华摘要、对话体重构、社交媒体切片)和多种输出格式(Markdown、微信公众号、知乎、企业内刊)。触发词:播客文章、播客转文章、podcast to article、podcast article
- 记录
touchstart时间和位置,touchend时算出持续时间和位移 - 如果
duration ,认为是轻点或微调,强制显示底部栏 - 注意:H5 下
touchend可能不触发(比如快速滚动后松手),所以主逻辑仍以onPageScroll为准,touchend只作修正 - 避免在
touchend里直接操作 DOM,统一走 Vue data 更新触发视图重绘
真机调试时底部栏闪动或错位怎么办
常见于微信小程序和 iOS App:因为状态栏高度、安全区、tabBar 隐藏逻辑互相干扰。uni-app 的 uni.getSystemInfoSync().statusBarHeight 在某些机型返回 0,导致计算偏移错误。
- 固定底部栏高度别硬编码,用
env(safe-area-inset-bottom)替代constant(safe-area-inset-bottom)(后者已废弃) - 微信小程序中,如果用了自定义 tabBar,
showTabBar/hideTabBarAPI 会与你的底部栏冲突,务必禁用自带 tabBar(tabBar设为空数组) - App 端启用
softinputMode: adjustResize后,键盘弹出会触发额外 scroll,导致误判隐藏——加个isKeyboardActive标记过滤 - 最稳的做法:所有 bottom 相关定位都用
calc(100vh - var(--window-bottom)),而不是依赖 JS 计算
实际做下来,最难的不是动画本身,而是不同平台对“滚动事件”的采样精度和触发时机差异。尤其是 iOS 微信里,onPageScroll 可能 300ms 才触发一次,所以阈值和防抖参数得实测调整,不能照搬 Android 数据。










