如何使用MutationObserver监听video视频加载完成事件?
问题原因
MutationObserver 的设计定位是监听DOM节点的结构、属性、文本内容变更,而视频加载完成属于媒体元素的内部资源加载状态变更,不属于DOM层面的变化,因此无法通过MutationObserver直接监听到该时机,属于API选型不匹配的问题。
解决方案
根据你的使用场景可以选择两种实现方式:
场景1:已经可以直接获取到video节点
直接使用video元素自带的媒体事件即可,你需要的「视频可正常显示后移除加载动画」的需求,绑定loadeddata事件即可实现,该事件会在视频首帧数据加载完成、可渲染时触发。
// 视频可渲染时触发 videoNode.addEventListener('loadeddata', () => { console.log('视频加载完成可显示') // 此处写你的移除加载动画逻辑 }) // 可选监听加载失败事件,避免加载动画一直展示 videoNode.addEventListener('error', (e) => { console.error('视频加载失败', e) // 移除动画+展示错误提示的逻辑 })
你可以根据实际需求替换监听的事件类型:
- 仅需要获取视频时长、尺寸等元数据时使用
loadedmetadata - 需要视频加载到可流畅播放全程再移除动画时使用
canplaythrough
补充兼容逻辑:如果视频存在缓存,可能绑定事件前就已经加载完成,可先判断readyState避免事件漏触发:
// readyState >=2 代表已经加载了至少首帧数据可显示 if (videoNode.readyState >= 2) { console.log('视频已缓存,直接移除动画') // 执行移除动画逻辑 } else { videoNode.addEventListener('loadeddata', 回调逻辑) }
场景2:video节点是后续动态插入页面的
可以配合MutationObserver监听父容器的子节点变化,识别到video插入后再绑定媒体事件:
// 替换为你要监听的video父容器节点 const parentContainer = document.querySelector('.video-wrapper') const observer = new MutationObserver((mutations) => { for (const mutation of mutations) { // 遍历所有新增的节点 for (const node of mutation.addedNodes) { if (node.tagName === 'VIDEO') { // 识别到video节点后绑定加载事件 node.addEventListener('loadeddata', () => { console.log('动态插入的视频已加载完成') // 移除加载动画 observer.disconnect() // 不需要继续监听时可销毁实例 }) } } } }) observer.observe(parentContainer, { childList: true, // 监听子节点增删变化 subtree: true // 可选:是否监听所有后代节点的变化 })
内容的提问来源于stack exchange,提问作者Captain-tab
相关产品推荐
相关产品推荐

