uni-app中实现标题栏滑动渐变需启用自定义导航栏,通过onpagescroll监听scrolltop计算透明度,用rgba动态设置背景色,避免scroll-view拦截滚动,并注意各端渲染差异与性能优化。

uni-app 中用 onPageScroll 监听滚动并动态修改标题透明度
小红书笔记页顶部标题在滑动时从透明渐变为不透明,本质是监听页面滚动距离,动态控制导航栏或标题元素的 opacity 或 rgba 颜色值。uni-app 里不能直接用原生 window.onscroll,必须依赖 onPageScroll 生命周期钩子。
注意:该钩子仅在启用了 "enablePullDownRefresh": false 且页面使用了 scroll-view 或原生滚动(即未禁用页面滚动)时才生效;若页面包裹了 scroll-view,则需监听其 bindscroll 事件而非 onPageScroll。
-
onPageScroll返回的是页面整体滚动的{ scrollTop: number },单位为 px - 建议设置一个临界值(如
100),当scrollTop 时,标题透明度 = <code>scrollTop / 100;超过后固定为1 - 避免在
onPageScroll中频繁调用this.setData(小程序端)或this.$forceUpdate(Vue2),应加节流(如setTimeout去抖)
自定义导航栏 + 动态 background-color 渐变
uni-app 的原生导航栏(navigationStyle: default)无法直接控制标题颜色/背景色渐变,必须设为 custom,自己手写顶部区域。否则即使改了标题 opacity,原生导航栏仍会遮挡或颜色突变。
常见错误:只改标题文字透明度,但没处理导航栏背景,导致“文字透出底下内容”却“导航栏还是白的”,视觉断裂。
- 在
pages.json中对应页面配置:"navigationStyle": "custom" - 在页面中用
<view class="nav-bar"></view>替代原生栏,并绑定:style="{ backgroundColor: navBg }" -
navBg计算逻辑示例:rgba(255, 255, 255, Math.min(scrollTop / 120, 1)),让背景从透明白渐变为纯白 - Android 上
statusBar会透出,需配合uni.setNavigationBarColor同步调整状态栏背景(iOS 不支持动态改状态栏颜色)
图片视差与标题错位问题怎么防
小红书详情页顶部常有一张大图,滑动时图片上移、标题相对“悬停”,形成视差。uni-app 没有内置视差组件,靠绝对定位 + transform: translateY() 模拟时,容易因不同平台渲染差异导致标题偏移或抖动。
根本原因:H5 端用 transform 安全,但小程序端(尤其微信)对 position: fixed + transform 组合支持不稳定,且 onPageScroll 的 scrollTop 在不同端返回精度不同(H5 是小数,小程序多为整数)。
- 不要用
fixed定位标题,改用position: sticky(H5 支持好,小程序不支持,需降级) - 更稳妥做法:把标题放在页面顶部的
view内,随内容一起滚动,再通过margin-top负值+z-index拉高层级,模拟悬停 - 视差图建议用
background-attachment: fixed(仅 H5),小程序必须用scroll-view+bindscroll+transform手动计算偏移
性能敏感点:别在滚动中触发 setData 或请求
很多开发者在 onPageScroll 里顺手加了 uni.showLoading 或接口调用,结果一滑就卡顿——这是最典型的误用。
onPageScroll 在 iOS 微信小程序中每秒可能触发 30–60 次,H5 更高频。任何同步 DOM 操作、setData、console.log 都会立刻拖慢帧率。
- 只做纯计算:opacity、color、transform 值推导,不读取或修改非响应式数据
- 如需联动其他状态(比如滚动到某位置显示按钮),用
if (scrollTop > X && !this.shown)加标记位,避免重复赋值 - 真要发请求,务必加防抖(
clearTimeout+setTimeout),且延迟至少300ms
实际中最容易被忽略的是:iOS 小程序里 onPageScroll 在页面刚打开时可能不会立即触发,首次滚动前标题状态是“未初始化”的,得在 onLoad 里先设一次默认样式。











