HTML视频启动图显示异常:解决setTimeout异步引发的黑色占位问题
解决视频启动图提前消失/黑色占位问题
1. 修正布局,确保启动图覆盖视频
当前布局中视频与启动图为垂直排列,并未实现重叠覆盖。需调整CSS让启动图绝对定位在视频上方:
.container{ height:300px; width:500px; position: relative; /* 为绝对定位提供参考容器 */ overflow: hidden; } video{ width: 100%; height:100%; position: absolute; top: 0; left: 0; z-index: 1; /* 视频置于下层 */ } img{ width: 100%; height:100%; object-fit: cover; position: absolute; top: 0; left: 0; z-index: 10; /* 启动图置于视频上方 */ }
2. 修复定时器冲突,确保单次有效计时
多次调用displaySplashScreen会创建重复定时器,导致启动图意外隐藏。需在每次调用时清除旧定时器,并确保启动图加载完成后再开始计时:
let videoUri: string; let splashImg: string = ... let showSplash: boolean = true; let splashTimer: number | null = null; // 存储定时器ID const displaySplashScreen = () => { // 清除之前的定时器,避免冲突 if (splashTimer) { clearTimeout(splashTimer); } showSplash = true; // 等待启动图加载完成后再启动倒计时 const splashElement = document.querySelector('.container img'); if (splashElement && !(splashElement as HTMLImageElement).complete) { (splashElement as HTMLImageElement).addEventListener('load', startSplashTimer, { once: true }); } else { startSplashTimer(); } }; const startSplashTimer = () => { splashTimer = setTimeout(() => { showSplash = false; splashTimer = null; }, 3000); }; // 监听src变化 $: if(src){ displaySplashScreen() } // 初始挂载执行 onMount(()=>{ displaySplashScreen() })
3. 结合视频加载状态优化(可选)
若想避免视频未加载完成时的黑色占位,可同时监听视频第一帧加载事件,取「3秒计时结束」和「视频+启动图加载完成」中较晚的时机隐藏启动图:
const displaySplashScreen = () => { if (splashTimer) clearTimeout(splashTimer); showSplash = true; let splashLoaded = false; let videoLoaded = false; const startTime = Date.now(); // 监听启动图加载 const splashElement = document.querySelector('.container img'); if (splashElement && !(splashElement as HTMLImageElement).complete) { (splashElement as HTMLImageElement).addEventListener('load', () => { splashLoaded = true; checkHideSplash(); }, { once: true }); } else { splashLoaded = true; } // 监听视频第一帧加载 const videoElement = document.querySelector('.container video'); if (videoElement) { if (videoElement.readyState >= 2) { // 已加载当前帧 videoLoaded = true; } else { videoElement.addEventListener('loadeddata', () => { videoLoaded = true; checkHideSplash(); }, { once: true }); } } // 启动3秒计时器 setTimeout(checkHideSplash, 3000); // 满足所有条件后隐藏启动图 const checkHideSplash = () => { if (splashLoaded && videoLoaded && Date.now() - startTime >= 3000) { showSplash = false; splashTimer = null; } }; };
4. 修正模板DOM错误
HTML模板中结束标签格式错误,需将<div/>改为</div>:
<div class="container"> <video src={videoUri} /> {#if showSplash} <img src={splashImg} /> {/if} </div>
内容的提问来源于stack exchange,提问作者lache
相关产品推荐
相关产品推荐

