遍历含数组与嵌套对象的JS对象:视频弹窗触发逻辑问题
解决视频弹窗逐个展示的问题
你的问题核心是没控制弹窗的展示顺序,直接循环会同步执行所有弹窗创建逻辑,导致它们同时出现。要实现逐个展示后再继续播放,需要用异步队列+暂停/恢复视频的方式处理。
核心思路
- 触发弹窗事件时(比如视频切换、播放到指定时间点),先暂停视频。
- 将对应视频的弹窗数组作为队列,逐个展示弹窗,等待用户关闭当前弹窗后再显示下一个。
- 所有弹窗展示完毕后,恢复视频播放。
代码实现
先保留你原有的弹窗数据:
let popups = { 0: [{ type: 'alert', text: 'Alert text', }, { type: 'warning', text: 'Warning text', }, ], 1: [{ type: 'caution', text: 'Caution text', }, ], };
然后实现弹窗控制逻辑:
// 获取视频元素(替换成你的视频DOM ID) const video = document.getElementById('video-player'); // 封装弹窗展示函数,返回Promise,关闭时触发resolve function showPopup(popup) { return new Promise((resolve) => { // 创建弹窗DOM const popupEl = document.createElement('div'); popupEl.style.cssText = ` position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); padding: 20px; background: white; border: 1px solid #ccc; z-index: 1000; `; popupEl.className = `popup popup-${popup.type}`; popupEl.innerHTML = ` <p>${popup.text}</p> <button class="popup-close">关闭</button> `; // 绑定关闭事件 const closeBtn = popupEl.querySelector('.popup-close'); closeBtn.addEventListener('click', () => { document.body.removeChild(popupEl); resolve(); // 弹窗关闭,通知队列继续 }); document.body.appendChild(popupEl); }); } // 处理指定视频索引的弹窗队列 async function processPopupQueue(videoIndex) { const queue = popups[videoIndex] || []; if (!queue.length) return; // 暂停视频 video.pause(); // 逐个遍历弹窗,等待每个弹窗关闭后再处理下一个 for (const popup of queue) { await showPopup(popup); } // 所有弹窗处理完毕,继续播放视频 video.play(); } // 示例:切换到索引0的视频时触发弹窗队列 processPopupQueue(0);
扩展:按视频播放时间触发弹窗
如果弹窗绑定到视频特定时间点,可以监听timeupdate事件触发:
// 时间点到弹窗的映射(示例) const timePopups = { 3: [{ type: 'alert', text: '视频播放到3秒了' }], 7: [{ type: 'warning', text: '注意!' }, { type: 'info', text: '继续观看' }] }; // 记录已触发的时间点,避免重复触发 const triggeredTimes = new Set(); video.addEventListener('timeupdate', () => { const currentTime = Math.floor(video.currentTime); if (timePopups[currentTime] && !triggeredTimes.has(currentTime)) { triggeredTimes.add(currentTime); // 调用队列处理函数 (async () => { await processPopupQueueByTime(currentTime); })(); } }); async function processPopupQueueByTime(timePoint) { const queue = timePopups[timePoint] || []; if (!queue.length) return; video.pause(); for (const popup of queue) { await showPopup(popup); } video.play(); }
内容的提问来源于stack exchange,提问作者WesCritch
相关产品推荐
相关产品推荐

