多视频上传预览重复问题求助 - JavaScript/jQuery
多视频预览重复问题的修复方案
问题根源
- 循环变量的闭包陷阱:你用
var声明循环里的file变量,它是函数级作用域,所有闭包(比如reader.onload)共享同一个file引用。循环结束后,file指向最后一个视频文件,导致所有预览都加载最后一个视频的Blob URL。 - 冗余的FileReader操作:视频预览不需要通过
FileReader读取DataURL,直接用URL.createObjectURL()生成Blob URL就足够,多余的异步操作反而加剧了变量引用问题。 - 全局变量污染:
ctx没有用var/let/const声明,变成全局变量,每次循环都会被覆盖,画布绘制逻辑也会出错。
修复后的完整代码
HTML(不变)
<div id="thumbnail"></div> <input type="file" id="upload-file" accept="video/*" multiple/>
JavaScript
$('div').on('click', '.closeDiv', function () { $(this).prev().remove(); $(this).remove(); $('#upload-file').val(""); }); var fileInput = document.getElementById("upload-file"); fileInput.addEventListener("change", function (e) { showThumbnail(this.files); }, false); function showThumbnail(files) { for (let i = 0; i < files.length; i++) { // 用let声明file,确保每次迭代有独立作用域 let file = files[i]; let thumbnail = document.getElementById("thumbnail"); let pDiv = document.createElement("div"); let video = document.createElement("video"); let div = document.createElement("div"); pDiv.setAttribute('class', 'pDiv'); thumbnail.appendChild(pDiv); video.setAttribute('class', 'imgKLIK5'); pDiv.appendChild(video); div.innerHTML = "Excluir"; div.setAttribute('class', 'closeDiv'); pDiv.appendChild(div); // 直接生成Blob URL,无需FileReader let blobURL = URL.createObjectURL(file); video.src = blobURL; video.setAttribute("controls", ""); // 画布绘制逻辑修复:用块级作用域变量 let canvas = document.createElement("canvas"); let ctx = canvas.getContext("2d"); video.onloadeddata = function () { ctx.drawImage(video, 0, 0, canvas.width, canvas.height); // 如果需要把画布作为缩略图,可以在这里把canvas添加到DOM // pDiv.appendChild(canvas); }; } }
关键修复点说明
- 用
let替代var声明循环变量:let是块级作用域,每次循环迭代都会创建新的file变量,闭包能正确绑定当前迭代的文件对象。 - 移除冗余的FileReader:直接使用
URL.createObjectURL(file)生成视频的预览地址,既简化代码又避免异步回调的变量引用问题。 - 修复画布变量作用域:把
canvas和ctx用let声明在循环块内,避免全局污染,确保每个视频对应独立的画布上下文。 - 替换
video.onload为video.onloadeddata:视频元素没有onload事件,用onloadeddata才能正确捕获视频加载完成的时机,执行画布绘制。
内容的提问来源于stack exchange,提问作者cesarpowerr20
相关产品推荐
相关产品推荐

