必须由用户手势(如@tap)触发uni.createVideoContext().requestFullScreen(),且需传入正确video id;iOS微信强制横屏须设direction:90并引导用户解锁屏幕方向。

点击视频立刻全屏,在小程序端必须用 uni.createVideoContext + requestFullScreen(),且触发动作必须是用户手势(如 @tap),不能靠 @loadedmetadata 或 @play 自动调;H5 和 App 端可放宽,但 iOS Safari 仍需手动触发。
为什么直接 @tap="requestFullScreen" 有时不生效?
微信小程序和部分安卓 WebView 对全屏 API 有严格限制:只有由用户真实触摸事件(@tap)发起的调用才被允许。以下写法会失败:
-
@play中调用requestFullScreen()→ 浏览器认为非用户主动,静默拒绝 -
@loadedmetadata中调用 → 同样被拦截,控制台可能无报错但无反应 - 用
setTimeout延迟 0ms 再调用 → 仍算异步,失去手势上下文
正确做法是把全屏逻辑绑定在视频区域本身的 @tap 上,并确保该区域可被点击(例如关闭 controls 后加一层透明 cover-view,或保留原生控制条里的全屏按钮)。
uni.createVideoContext 调用时容易漏掉什么?
uni.createVideoContext 必须传入 video 组件的 id,且该 id 要与模板中一致;在 Vue 3 的 setup 语法下,还需注意 this 上下文问题。常见疏漏:
- video 没写
id属性,只写了ref→createVideoContext找不到目标 - H5 端误用
this.$refs.videoPlayer直接调requestFullscreen()→ 应统一走uni.createVideoContext跨端兼容 - 在
onLoad阶段就创建 context,但此时 video 尚未挂载 → 推荐在onReady或首次@tap时再创建
示例写法:
<video id="mainVideo" src="https://xxx.mp4"></video>
methods: {
handleVideoTap() {
const ctx = uni.createVideoContext('mainVideo', this)
ctx.requestFullScreen({ direction: 90 }) // 强制横屏
}
}
如何让点击后“看起来就是全屏”,而不是等系统动画?
原生 requestFullScreen() 有平台级过渡动画(尤其 iOS),用户会感知延迟。若想视觉上更即时,可在 @tap 同时提前切换样式:
- 给 video 加 class:
is-fullscreen,CSS 设置width: 100vw; height: 100vh; position: fixed; top: 0; left: 0; z-index: 9999; - 立即隐藏其他 UI 元素(如导航栏、侧边栏)
- 再调
ctx.requestFullScreen()—— 此时视觉已“全屏”,系统动画只是补全底层状态 - 监听
@fullscreenchange,若失败(e.detail.fullScreen === false),则手动还原样式
注意:此方案在小程序端要慎用 position: fixed,建议改用 cover-view 包裹 video 实现同层渲染,否则可能被截断或层级错乱。
direction 参数怎么选才不翻车?
requestFullScreen({ direction: X }) 的 X 值决定旋转方向,但不同端表现不一:
-
0:自动判断(微信小程序支持,iOS 不支持,H5 无效) -
90:强制横屏(多数场景推荐,尤其短视频) -
-90:逆时针横屏(极少用) -
180:竖屏倒置(基本不用)
关键点:iOS 微信里 direction: 0 会被忽略,默认竖屏;若你明确要横屏,必须写 90。另外,direction 只影响进入全屏时的方向,退出后不会自动恢复页面 orientation,需自行监听 onOrientationChange 处理。
最易被忽略的是:iOS 微信中,即使调用了 requestFullScreen({ direction: 90 }),如果当前设备处于竖屏锁定状态,它依然不会横屏 —— 这不是代码问题,是系统策略。所以真正在意横屏体验的业务,得在 UI 上引导用户解锁屏幕方向。











