navigationStyle: "custom" 是前提,pages.json 中需配置该值才能启用 --status-bar-height 变量和 uni.setStatusBarStyle;小程序不支持原生导航栏透明,App 端需用 uni.setStatusBarStyle 控制 iOS 状态栏文字色,Android 需平台判断;透明效果应采用背景图加渐变遮罩实现,滚动时仅动态调整渐变 alpha 值,并节流 onPageScroll、防负 scrollTop、批量更新 data。

navigationStyle: "custom" 是前提,不是结果
不设这个,后续所有操作都无效。pages.json 里对应页面的 style 节点下必须写 "navigationStyle": "custom",否则 --status-bar-height 变量不可用,uni.setStatusBarStyle 也对状态栏文字无影响。小程序端即使写了也无效——它压根不支持原生导航栏透明,只能手写 fixed 导航栏并控制其自身透明度,和系统状态栏是两层事。
App 端状态栏文字颜色必须用 uni.setStatusBarStyle
uni.setNavigationBarColor 在 navigationStyle: "custom" 下完全不生效,它只管原生导航栏背景。而你看到的状态栏文字(时间、信号、电量)由系统独立渲染,iOS 上必须调 uni.setStatusBarStyle('light') 或 'dark' 才能切换文字颜色。Android 不支持该 API,需加平台判断:
if (uni.getSystemInfoSync().platform === 'ios') {
uni.setStatusBarStyle(navOpacity < 0.4 ? 'dark' : 'light')
}
注意时机:不能只在 onLoad 调一次,得和滚动状态联动,在 onPageScroll 里根据 navOpacity 实时更新。
透明度不能只靠 background-color 的 alpha
- 单纯设
background-color: rgba(255,255,255,0.3)会让文字发虚,尤其 iOS WebKit 渲染下明显 - 真正可用的是「背景图 + 渐变遮罩」组合:
background-image: url(...)拉满,再叠一层linear-gradient(rgba(0,0,0,0.1), rgba(0,0,0,0.1))控制透出程度 - 滚动时只动态改渐变层的 alpha 值,底图保持不变,避免重绘抖动
- 如果用
<u-navbar>,它的background属性不接受 CSS 渐变字符串,得传对象:{ backgroundImage: 'linear-gradient(...)', backgroundSize: '100% 100%' }
滚动监听必须节流,且 scrollTop 要防负值
iOS 下拉回弹时 onPageScroll 会返回负的 scrollTop,直接用于计算会导致 opacity 变成负数或 NaN。正确写法是:
const safeTop = Math.max(0, e.scrollTop) const fadeRange = 120 const navOpacity = Math.min(1, safeTop / fadeRange)
还要加节流,不然低端安卓机滚动卡顿:
- 用
lastTime时间戳控制最小间隔 ≥16ms - 别在
onPageScroll里直接调this.$forceUpdate()或频繁setData - 合并更新:opacity、文字色、渐变层透明度用一个
data对象批量赋值
最易被忽略的一点:H5 和小程序端的 onPageScroll 触发逻辑不同。H5 默认可用;微信小程序若页面没包 <scroll-view>,某些 iOS 微信版本可能不触发——得在 pages.json 里确认没开 enablePullDownRefresh,否则原生下拉会劫持滚动事件。


















