uni.onwindowresize 不响应状态栏高度变化,仅响应窗口尺寸变化;真正可用的是 onpagescroll + 高度推算,需原生滚动且节流处理,微信小程序中该需求本质不成立。

uni.onWindowResize 不是状态栏高度监听事件
很多人搜“状态栏高度改变”会误用 uni.onWindowResize,但它只响应窗口尺寸变化(比如横竖屏切换、分屏),**不响应状态栏高度变化**。iOS 状态栏在来电、录音、刘海屏适配等场景下可能动态变高或隐藏,Android 也在全面屏手势/沉浸式模式下频繁调整,这些都不会触发 uni.onWindowResize。
真正能捕获状态栏高度变化的只有 onPageScroll + 高度推算
uni-app 没有提供类似 onStatusBarHeightChange 的原生事件。目前唯一稳定、跨端可用的方式是:利用 onPageScroll 监听滚动,结合页面根容器实际渲染高度与内容高度差,反推出状态栏区域是否被系统占用或调整。
- 前提:页面必须启用原生滚动(即未包裹
<scroll-view></scroll-view>),且pages.json中未设"disableScroll": true - 在
onPageScroll回调中,e.scrollTop是页面顶部到视口顶部的距离,这个值在状态栏高度变化瞬间会出现微小跳变(尤其 iOS 微信真机) - 可配合
uni.getSystemInfoSync().statusBarHeight做基准比对,但注意该值是静态常量,无法反映运行时变化;真正的动态变化只能靠滚动偏移突变来感知 - 高频触发需节流,建议用
setTimeout+ 标志位控制每 200ms 最多响应一次,避免误判
Android FLAG_FULLSCREEN / iOS 沉浸式导致状态栏消失,怎么检测
当 App 启用沉浸式(如 Android 设置 FLAG_FULLSCREEN 或 iOS 设置 UIStatusBarHidden = YES),状态栏会完全隐藏,此时 statusBarHeight 仍返回默认值(如 20 或 44),但视觉上已不可见。这种变化无法通过 JS 监听,必须依赖原生层回调。
- 若使用原生插件(如
uni-secure-statusbar),它通常会在状态栏显隐时触发自定义事件,例如statusbar:changed,需手动uni.$on('statusbar:changed', ...) - 纯 JS 方案只能降级为定时轮询:用
setInterval每秒调一次uni.createSelectorQuery()查询顶部安全区域元素(如一个固定top: 0的<view></view>)的boundingClientRect,看其top是否从 0 变为正数 - 该方法性能差、耗电高,仅作兜底;H5 端可通过
window.matchMedia('(prefers-status-bar-style: light)')间接感知,但不精确
最易被忽略的一点:微信小程序里 status bar 高度根本不会“动态改变”
微信小程序运行在 WebView 容器内,状态栏由微信客户端统一管理,**JS 层无法感知其运行时高度变化**。所谓“来电时状态栏变高”,实际是微信主动将整个 WebView 下压,而 uni-app 的 onPageScroll 和布局计算都基于 WebView 视口,不会暴露这一层系统行为。因此,在微信小程序中,“监听状态栏高度改变”本身是个伪需求——你真正该做的是适配不同机型的固定 statusBarHeight,并在 onLoad 里用 uni.getSystemInfoSync() 获取并缓存。











