uni.onWindowResize是App端唯一可靠的方向监听方式,需在onReady注册、onUnload清理,通过windowWidth与windowHeight判断横竖屏,配合响应式变量和CSS类切换实现布局适配,避免直接DOM操作或transform旋转。

uni.onWindowResize 是 App 端唯一可靠的方向监听方式
App 端无法用 window.orientation 或 screen.orientation 监听旋转——iOS Safari 不支持,Android 原生 WebView 也不暴露该对象;orientationchange 事件在多数真机上根本不会触发。唯一跨 App 平台(iOS/Android)稳定可用的 API 是 uni.onWindowResize。
它返回的是实时视口尺寸,不是设备物理方向,但对 UI 布局足够:只要 windowWidth > windowHeight,就可认为用户已转为横屏(注意:极少数折叠屏或分屏场景下可能有例外,但普通手机 99% 准确)。
- 必须在
onReady中注册,onLoad太早,native view 尚未初始化,监听无效 - 必须在
onUnload中调用uni.offWindowResize清理,否则页面复用时会重复触发 - 不要依赖
res.size以外的字段,res对象结构各平台不一致,仅size.windowWidth和size.windowHeight可靠
监听到变化后,别直接改 DOM class 或 style
常见错误是拿到 windowWidth > windowHeight 后,立刻 document.querySelector('.video-wrap').style.transform = 'rotate(90deg)' —— 这在 App 端会导致触摸坐标错乱、Canvas 绘制偏移、输入框弹出异常,本质是“假横屏”,WebView 容器仍是竖屏状态。
正确做法是用响应式变量驱动样式切换:
- 定义一个响应式数据
isLandscape,在uni.onWindowResize回调里赋值 - CSS 用
@media (orientation: landscape)配合 class 切换,例如:<view :class="{ 'landscape-mode': isLandscape }"> - 避免内联 style,尤其不要对
<video>或<canvas>元素做 transform 旋转
video 全屏时方向重置必须手动补救
即使页面已锁定横屏,用户点击 <video> 右上角全屏按钮后,iOS WKWebView 会接管 orientation 控制权,导致画面瞬间切回竖屏——这不是 bug,是系统行为。
必须主动干预:
- 给
<video>加@fullscreen-change="onFullscreenChange" - 在
onFullscreenChange中判断detail.fullscreen === true,立即再调一次uni.setScreenOrientation({ orientation: 'landscape-primary' }) - 同时关闭
controls和enable-danmu,否则原生播放器路径会绕过 JS 层所有方向设置 - Android 上
fullscreen-change可能不触发,所以建议在videoContext.requestFullScreen()的 Promise resolve 后也补调一次
App 端运行时调用 uni.setScreenOrientation 的实际限制
这个 API 在 App 端效果非常有限:iOS 上基本静默失败,Android 上仅部分机型(targetSdkVersion ≥ 28 且 Activity 未硬编码 screenOrientation)才可能生效。它不是“切换方向”,而是“向系统申请方向”,是否采纳完全由 OS 决定。
真正可靠的横屏方案只有两种:
- 启动前配置:在
manifest.json的app-plus.distribute.ios.orientation设为["landscape-primary", "landscape-secondary"],Android 对应设"landscape",然后重新云打包 - 页面级隔离:把横屏页(如视频页、游戏页)单独做成一个原生 Activity(通过 subNVue 或自定义原生插件),其他页面保持竖屏
- 别在
onLoad里调uni.setScreenOrientation,iOS 启动动画未结束时调用大概率失效;加setTimeout也不是解法,只是掩盖问题
方向监听本身不难,难的是理解 App 端真正的控制权不在 JS 层——你写的每一行方向逻辑,都得先过原生配置这一关。


















