使用JavaScript DOM动态加载视频时onload回调不触发问题求解
现有代码的问题
- video元素不存在
onload事件,该事件仅适用于window、img等元素,视频加载完成的回调需要监听对应媒体事件,常用的有loadedmetadata(元数据加载完成)、canplay(可开始播放)、canplaythrough(可流畅播放到结束) - 创建的video元素没有被插入到当前页面的DOM树中,部分浏览器不会触发资源加载逻辑
- 现代浏览器的自动播放策略要求带声音的视频必须用户交互后才能触发播放,如果你需要自动播放必须同时设置
muted属性为true - 代码语法错误:
doAjaxVideo调用末尾缺少右括号 - 你观察到的accept头为
/的问题,是使用source元素挂载资源时的默认请求头行为,直接给video元素的src属性赋值即可解决该问题
修正后的可运行代码
function doAjaxVideo(param, lambda) { let video = document.createElement("video"); // 直接给video赋值src,不需要额外source元素,避免请求头异常 video.src = param; video.type = "video/webm"; // 自动播放必须设置静音,否则会被浏览器拦截,不需要自动播放可删除下行 video.muted = true; video.autoplay = true; // 监听正确的媒体加载事件,这里用canplay代表进入可播放状态时触发回调 video.addEventListener('canplay', () => lambda()); // 把video插入到DOM中,可替换为你需要挂载的自定义父元素 document.body.appendChild(video); } doAjaxVideo("/video.webm", function() { console.log("Ready!") });
其他实现方案
如果需要先预加载视频资源再渲染,可以用Fetch API先拉取资源,再转换为blob地址赋值给video,该方案可以完全自定义请求头,加载完成的时机也更可控:
async function preloadVideo(url, callback) { const res = await fetch(url); const videoBlob = await res.blob(); const video = document.createElement('video'); video.src = URL.createObjectURL(videoBlob); video.muted = true; video.autoplay = true; document.body.appendChild(video); callback(); } preloadVideo("/video.webm", () => console.log("Ready!"));
内容的提问来源于stack exchange,提问作者Jurby
相关产品推荐
相关产品推荐

