小红书笔记详情页滑动渐变效果核心是 onpagescroll 监听 scrolltop,设定阈值(如80px)后动态计算导航栏透明度与 box-shadow,配合 u-navbar 的 background 样式和 immersive=true 实现从透明到实色过渡,ios 需同步处理 statusbarheight 与 paddingtop 防错位。

直接说结论:小红书笔记详情页的滑动渐变效果,核心是「顶部导航栏随滚动从透明到实色过渡」,不是靠图片或遮罩,而是用 onPageScroll + 动态 background 样式控制,配合 UView 的 u-navbar 或原生 navigationStyle: custom 实现。H5 和小程序表现一致,但 iOS 真机需注意 immersive 与状态栏适配。
onPageScroll 怎么监听滚动并计算透明度
UniApp 的 onPageScroll 是唯一可靠入口,它返回 e.scrollTop(单位 px),不是百分比。别用 scroll-view 的 bindscroll —— 它在页面级滚动中不可靠,且无法触发自定义导航栏更新。
常见错误是直接拿 scrollTop 做透明度值,导致一开始就有半透效果。正确做法是设定一个「起始阈值」(比如 80px),超过才开始渐变:
- 当
scrollTop ≤ 80:透明度 = 0(完全透明) - 当
80 :透明度 = <code>(scrollTop - 80) / 120(线性过渡) - 当
scrollTop ≥ 200:透明度 = 1(完全不透明)
这个 80/200 不是 magic number,它对应你页面首屏内容高度和导航栏固定所需的临界点,需根据实际设计稿微调。
u-navbar background 怎么动态设置渐变色
u-navbar 的 background 属性接收对象,不是字符串。写成 background="rgba(255,255,255,0.8)" 会失效,必须用对象语法:
data() {
return {
boxStyle: {
background: 'transparent',
boxShadow: 'none'
}
}
},
onPageScroll(e) {
const opacity = Math.min(1, Math.max(0, (e.scrollTop - 80) / 120));
this.boxStyle = {
background: `rgba(255, 255, 255, ${opacity})`,
boxShadow: opacity > 0.1 ? '0 2rpx 10rpx rgba(0,0,0,0.06)' : 'none'
};
}
注意两点:
- 别漏掉
boxShadow的同步控制,否则边框会突兀出现 - 如果要用渐变色(如
linear-gradient),得把整个background拼成字符串并设为backgroundImage,但 iOS 微信小程序对backgroundImage支持不稳定,建议只用纯色+透明度
为什么 custom 导航栏在 iOS 上常“错位”或“盖住内容”
启用 navigationStyle: custom 后,uni-app 会移除原生导航栏,但不会自动给页面内容加 padding-top。结果就是:iOS 上状态栏区域(44px 高)被内容顶穿,尤其轮播图顶部被截断。
解决方案不是硬写 padding-top: 88rpx,而是分层处理:
- 用
uni.getSystemInfoSync().statusBarHeight获取真实状态栏高度(iOS 通常 44rpx,安卓可能 24~30rpx) - 在页面根容器上加
:style="{ paddingTop: statusBarHeight + 'px' }" - 同时确保
u-navbar的height和immersive配合:设immersive="true",且自身高度含状态栏(即总高 ≈ 88rpx)
漏掉其中任一环,都会导致 iOS 下导航栏悬浮、内容上滑时顶部露白或错位。
最易被忽略的是:渐变逻辑必须放在 onPageScroll 里,不能塞进 watch 或 computed;因为该生命周期是 uni-app 唯一保证与滚动帧率同步的钩子,其他方式必然掉帧或延迟。另外,真机调试务必关掉「调试器」里的「禁用硬件加速」选项,否则 iOS 上 transform 和 opacity 动画会卡顿。










