uni-app中video真全屏必须调用requestFullScreen(),CSS拉伸无效;需设id、用createVideoContext获取实例;仅@fullscreenchange事件可靠,须同步data状态;全屏时设body背景黑底防透出;iOS/小程序不支持自动全屏,须用户手势触发。

uni-app video 全屏必须用 requestFullScreen(),不能靠 CSS 拉伸
直接给 加 style="width: 100vw; height: 100vh;" 看似“全屏”,实际只是拉伸容器,视频内容仍被裁切、控制条错位、背景透出——这不是真全屏,iOS 和小程序里尤其明显。
真正触发系统级全屏,必须调用原生能力:uni.createVideoContext() 获取上下文后执行 requestFullScreen()。这个方法会唤起平台原生全屏逻辑(比如 iOS 的画中画切换、微信的横屏沉浸式播放)。
- 必须为
设置id属性,否则uni.createVideoContext('xxx')拿不到实例 - H5 端依赖浏览器支持,部分安卓 WebView 需用户手势(如点击)才能触发,不能在
@load或@canplay里静默调用 - 微信小程序要求
controls为true才允许调用requestFullScreen(),否则静默失败
@fullscreenchange 是唯一可靠的全屏状态监听方式
别信 document.fullscreenElement 或 screen.orientation —— 在 uni-app 多端环境下,这些原生 API 在 iOS 小程序、App(尤其是 iOS App)里基本不可靠,返回值常为空或滞后。
所有平台都统一走组件事件:@fullscreenchange,它在进入/退出全屏时准确触发,且 event.detail.fullscreen 返回布尔值,干净直接。
- 务必在 data 中声明状态变量(如
isFullscreen: false),并在事件回调里同步更新,用于条件渲染封面、隐藏底部栏等 - iOS 小程序里,用户按物理返回键退出全屏,也会触发该事件;但 H5 端按 ESC 不一定触发(取决于浏览器),需额外监听
document.onexitfullscreen做兜底(仅限 H5) - 不要在
@fullscreenchange里立刻调requestFullScreen()或exitFullScreen(),可能引发循环调用
背景透出问题:黑底不是装饰,是刚需
全屏时页面其他 DOM(比如 tabbar、导航栏、浮动按钮)仍可能“透”在视频下方,尤其在 iOS App 和某些安卓机上——这不是 bug,是渲染层级没压住。
最简单有效的解法:全屏时把 document.body.style.backgroundColor = '#000',退出时清空。比写一堆 z-index 和 position: fixed 更稳,且兼容所有平台。
- 别只改父容器背景,必须动
body或page根节点,否则小程序里无效 - 如果用了自定义导航栏(
navigationStyle: custom),要同时隐藏它,否则它会浮在黑底之上,形成“灰边” - cover-view 覆盖层只能用于按钮/文字等轻量 UI,不能塞复杂组件(如 swiper、map),否则 iOS 上会闪退或卡死
自动全屏?iOS 和微信小程序里基本做不到
想让视频一加载完就自动全屏?在 iOS(包括 App 和 Safari)和微信小程序里,这是被系统明确禁止的。没有用户点击/触摸动作作为起点,requestFullScreen() 会被静默拦截,控制台无报错,但就是不生效。
折中方案只有两个:一是放一个醒目的“全屏播放”按钮,绑定点击调用;二是监听首次 @play(用户点播放后),再立即 requestFullScreen() —— 这个时机 iOS 微信都认。
- 别在
@canplay、@loadeddata或mounted里尝试,必失败 - Android App 理论上支持自动全屏,但不同厂商 WebView 行为不一,建议也统一走用户触发路径,省去兼容判断
- 如果业务强依赖自动全屏(如信息流首刷),只能降级为“伪全屏”:用 cover-view + 动态 class 模拟,但要接受控制条不可用、无法横竖屏切换等限制
全屏这件事,表面是调一个函数,背后全是平台策略博弈。最易忽略的,是把 @fullscreenchange 当成可选监听,其实它是你唯一能信任的状态信标。











