
本文详解如何让自定义 html 测验元素(如 #affiche)在 vimeo 视频进入原生全屏模式后仍能正确显示于视频上方,解决因 iframe 沙箱隔离与 vimeo 全屏 dom 重构导致的 z-index 失效问题。
在嵌入 Vimeo 视频时,通过 CSS 定位将 HTML 测验层(如 <div id="affiche">)叠加在 <iframe> 上方,在常规非全屏状态下通常可正常工作——只需确保父容器为 position: relative,测验层设为 position: absolute 并赋予足够高的 z-index(例如 2147483647)。但一旦触发 Vimeo 的原生全屏(native fullscreen),问题立即出现:Vimeo 会将 <iframe> 自身提升至顶层渲染上下文(top layer),其内部 UI(如 vp-player-ui-overlays)完全接管视觉层级,外部 DOM 元素(即使 z-index 极高)也无法穿透 iframe 边界进行覆盖。
根本原因在于:浏览器原生全屏 API 仅允许被请求全屏的 DOM 元素(及其子元素)参与全屏渲染;iframe 外部的兄弟节点(如 #affiche)会被强制排除在全屏视口之外。 因此,试图通过修改 .player、.vp-video-wrapper 等 Vimeo 内部类名来“注入”覆盖层,或用 $("#affiche").appendTo($("iframe")) 尝试移入 iframe,均会失败——前者无权操作跨域 iframe 内容,后者违反同源策略且语法无效(appendTo 不能向 iframe 内容文档插入元素)。
✅ 正确解法:主动请求包含测验层的整个容器进入全屏,而非依赖 Vimeo 的 iframe 全屏。
这意味着你需要放弃 Vimeo 默认的 allowfullscreen 按钮,改用自定义全屏控制,并将 <iframe> 和 <div id="affiche"> 同时作为 .boiteVideo 的子元素,对该容器调用 requestFullscreen():
立即学习“前端免费学习笔记(深入)”;
<button id="btnFullScreen">进入全屏测验模式</button>
<div class="embed-responsive embed-responsive-16by9 boiteVideo">
<iframe id="player1"
src="https://player.vimeo.com/video/XXXXX?controls=0&autoplay=1"
frameborder="0"
allow="autoplay; fullscreen"
allowfullscreen>
</iframe>
<div id="affiche" class="text-success well" style="pointer-events: auto;">
<h1>Un test overlay</h1>
<p>Q1: 此刻视频播放到了哪个关键帧?</p>
<button class="btn btn-primary" onclick="submitAnswer('A')">选项 A</button>
</div>
</div>// 启用自定义全屏
document.getElementById('btnFullScreen').addEventListener('click', () => {
const container = document.querySelector('.boiteVideo');
if (container.requestFullscreen) {
container.requestFullscreen();
} else if (container.webkitRequestFullscreen) {
container.webkitRequestFullscreen();
} else if (container.msRequestFullscreen) {
container.msRequestFullscreen();
}
});
// 可选:监听退出全屏事件,恢复布局
document.addEventListener('fullscreenchange', () => {
if (!document.fullscreenElement) {
console.log('已退出全屏');
}
});.boiteVideo {
position: relative;
width: 100%;
height: 0;
padding-bottom: 56.25%; /* 16:9 */
overflow: hidden;
}
.boiteVideo iframe {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border: none;
}
#affiche {
position: absolute;
top: 200px;
left: 200px;
z-index: 1000; /* 在容器内有效即可,无需天文数字 */
background: rgba(255, 255, 255, 0.9);
padding: 20px;
border-radius: 8px;
max-width: 400px;
}⚠️ 关键注意事项:
- pointer-events: auto 必须显式设置在 #affiche 上(默认继承自父容器),否则全屏下可能失焦;
- Vimeo iframe 的 src 中建议添加 ?controls=0 隐藏原生控件,避免 UI 冲突;
- 使用 allow="autoplay; fullscreen" 确保权限兼容性;
- 若需响应式定位(如居中题干),推荐用 transform: translate(-50%, -50%) 配合 left: 50%; top: 50%;
- 如需与 Vimeo Player.js 同步测验时机,请监听 timeupdate 事件,在指定时间点动态 show()/hide() #affiche。
通过将测验层与视频 iframe 置于同一全屏容器内,你完全绕开了跨 iframe 渲染限制,获得稳定、可控、符合现代 Web 标准的交互式视频测验体验。











