uni-app video全屏需分端处理:App端调用videoContext.requestFullScreen(),H5需manifest.json开启orientation,鸿蒙需hardware解码;cover-view全屏失效是设计使然,覆盖须用subNVue或原生插件。

video 全屏播放不是加个 fullscreen 属性就行
uni-app 的 组件本身不支持原生 HTML 的 webkit-playsinline 或 allowfullscreen 等属性,直接写在标签上无效。App 端(iOS/Android)的全屏行为由原生播放器控制,必须通过 JS API 触发。
- 正确做法是调用
videoContext.requestFullScreen(),且仅在用户手势(如点击)回调中执行,否则 iOS 会静默拒绝 - H5 端需额外配置:在
manifest.json中开启"orientation": "all",否则横屏全屏失败 - 鸿蒙 OS 要求更严:必须配合
decode-mode="hardware"和enable-hardware-accelerate="true",否则全屏后黑屏或卡顿 - 全屏退出后,
videoContext可能失效,建议监听@fullscreenchange事件并重置引用
cover-view 在全屏时失效?这是设计使然,不是 bug
官方文档明确说明:cover-view 仅在非全屏状态下有效。一旦 video 进入原生全屏界面,它就脱离 WebView 上下文,cover-view 自然无法渲染——这不是兼容性问题,而是渲染层级切换的结果。
- 别试图给全屏状态下的
cover-view加v-if切换逻辑,它根本不会挂载 - 若需全屏时仍有控件(如返回按钮、进度条),唯一可靠方案是使用
subNVue,并在 pages.json 中配置其position: "dock"或"absolute"定位到屏幕右上角等固定位置 - 注意:subNVue 的
zIndex必须 ≥ 9999 才能压住鸿蒙/Android 原生全屏控件层
想盖住 video,别碰 z-index,碰了也没用
z-index 对 无效,因为它的渲染层在 WebView 之上,属于系统级 SurfaceView / AVPlayerLayer。所有基于 CSS 层叠上下文的尝试(包括 position: fixed + 高 z-index)在 App 端必然失败。
- 真要覆盖,只认三个东西:
cover-view(非全屏)、subNVue(全屏/非全屏都行)、原生插件(如自定义播放器 SDK) -
cover-view内不能放,只能嵌套cover-image和cover-view,且不支持background-image、transform、animation - Android 上若发现
cover-view闪烁或错位,大概率是父容器用了scroll-view,必须把cover-view提到页面最外层(同级于scroll-view),否则滚动时定位丢失
subNVue 不是银弹,滚动场景下定位容易“钉死”屏幕
用 subNVue 覆盖视频确实能解决层级,但很多人忽略它的定位机制:默认 position: "absolute" 是相对于整个窗口(Window),不是相对于父页面。页面一滚动,弹窗就悬在半空不动,像贴了胶水。
- 如果视频区域本身可滚动(比如竖屏短视频流),不要让
video和subNVue同属一个滚动容器;应把视频设为height: 100vh固定,其他内容用独立scroll-view - 需要跟随滚动?只能改用
position: "static",但此时top/left失效,得靠nvue页面内 flex 排布+占位元素对齐,灵活性极低 - iOS 上 subNVue 动画卡顿常见于未关闭
debug模式,发布前务必检查 HBuilderX 的「运行 → 运行到手机或模拟器」是否勾选了「调试基座」
实际项目里最常被绕开的点是:没区分「全屏中」和「非全屏」两种状态分别处理覆盖逻辑。一套代码打天下,在鸿蒙和 iOS 上必然出事。











