JavaScript实现多视频文件上传时获取视频时长问题求助
多视频上传获取时长功能:问题排查与修复
核心问题分析
原代码存在以下几个关键错误:
- 闭包变量陷阱:循环使用
var i,异步回调onloadedmetadata触发时,循环已执行完毕,i值为files.length,导致myVideos[i]指向undefined,无法设置时长。 - 未定义变量引用:
updateInfos函数中total += myVideos[i].duration的i未定义,应使用当前循环变量j。 - 原生File对象限制:直接给只读的File对象添加
duration属性可能失效,需用自定义对象包装文件信息。 - 异常值未处理:时长加载完成前调用
updateInfos会显示NaN,需做默认值兼容。
修正后的完整代码
HTML(无需修改)
<div id="input-upload-file" class="box-shadow"> <span>- Try Upload -</span> <input type="file" class="upload" id="fileUp" name="fileUpload" multiple onchange="setFileInfo(this.files)"> </div> <div id="infos"></div>
JavaScript(修复版)
const formatSeconds = seconds => { if (isNaN(seconds)) return "00:00:00"; return new Date(seconds * 1000).toISOString().substr(11, 8); }; let myVideos = []; window.URL = window.URL || window.webkitURL; function setFileInfo(files) { for (let i = 0; i < files.length; i++) { // 用自定义对象包装文件信息,避免修改原生只读File对象 const videoItem = { file: files[i], duration: 0 }; myVideos.push(videoItem); const video = document.createElement('video'); video.preload = 'metadata'; video.src = URL.createObjectURL(files[i]); // 箭头函数绑定当前videoItem,彻底避免闭包索引问题 video.onloadedmetadata = () => { window.URL.revokeObjectURL(video.src); videoItem.duration = video.duration; updateInfos(); }; } } function updateInfos(deleteName) { const info = document.querySelector('#infos'); info.innerHTML = ""; let total = 0; // 处理删除逻辑:用filter简化数组操作 if (deleteName) { myVideos = myVideos.filter(item => item.file.name !== deleteName); } // 遍历渲染所有视频信息 myVideos.forEach(item => { info.innerHTML += `<div class='row' data-name='${item.file.name}'> <div class='close' onclick="remove(this)">×</div> ${item.file.name}, duration: ${formatSeconds(item.duration)} </div>`; total += item.duration; }); // 显示总时长 if (myVideos.length) { info.innerHTML += `<div class='row'>Total: ${formatSeconds(total)}</div>`; } } function remove(e) { updateInfos(e.parentNode.dataset.name); }
修复关键点说明
- 块级作用域变量:用
let i替代var i,确保每个循环迭代的回调能捕获正确的索引值。 - 自定义对象包装:用
videoItem封装File对象和时长属性,绕过原生File对象的只读限制。 - 简化删除逻辑:使用
filter方法替代倒序循环删除,代码更简洁且避免索引异常。 - 异常值处理:在
formatSeconds中增加NaN判断,避免未加载完成时显示错误内容。 - 箭头函数规避闭包问题:直接引用当前循环的
videoItem,彻底解决异步回调的变量绑定错误。
内容的提问来源于stack exchange,提问作者omar yaser
相关产品推荐
相关产品推荐

