在jQuery fadeIn()回调中调用URL.createObjectURL触发TypeError错误
解决fadeIn回调中event未定义导致的图片预览错误
问题场景
原本代码可正常实现图片先在浏览器端预览、再上传至服务器的功能。现在想给两次上传过程添加进度条,并在fadeIn()执行完成后启动进度条逻辑,但将代码放入fadeIn()的回调函数时,出现如下错误:
Uncaught TypeError: Cannot read properties of undefined (reading 'target')
at HTMLDivElement.
错误触发点为URL.createObjectURL(event.target.files[i])这一行。
错误原因
upload_to_browser由文件输入框的onchange事件触发,原本的event是该change事件的参数,但回调函数的上下文已改变——此时event指向的是jQueryfadeIn方法的事件对象,而非文件选择的change事件对象,因此无法读取target属性。
修复方案
1. 修正浏览器端预览的代码
提前保存文件输入框的DOM引用,直接从DOM中获取文件列表,避免依赖event对象:
// 将图片HTML写入iframe function upload_to_browser(event) { // 接收change事件的event参数(兼容原有调用) var html = ""; var fileInput = document.getElementById("files"); var total_files = fileInput.files.length; var progressbar = $(".progressbar").progressbar({ max: total_files }).fadeIn(200, function () { for (var i = 0; i < total_files; i++) { var file = fileInput.files[i]; // 直接从DOM元素获取文件,无需依赖event html += `<img id='image${i}' width=100 height=100 src='${URL.createObjectURL(file)}'>`; } document.getElementById("image_preview").contentDocument.write(html); // 模拟浏览器端预览的进度更新 for(let i = 1; i <= total_files; i++) { setTimeout(() => { progressbar.progressbar("value", i); }, 200 * i); // 可根据实际预览速度调整间隔 } }); }
同时修改HTML中onchange的调用,传递event参数(确保兼容性):
<input type="file" id="files" name="upload_file[]" onchange="upload_to_browser(event);" accept="image/png, image/gif, image/jpeg" multiple />
2. 服务器上传的进度条实现
使用XMLHttpRequest的upload.progress事件监听真实上传进度:
function upload_to_server() { var fileInput = document.getElementById("files"); var formData = new FormData(); // 构建FormData for(let i = 0; i < fileInput.files.length; i++) { formData.append("upload_file[]", fileInput.files[i]); } var xhr = new XMLHttpRequest(); var progressbar = $(".progressbar").progressbar({ max: 100 }).fadeIn(200); // 监听上传进度 xhr.upload.addEventListener("progress", function(e) { if (e.lengthComputable) { var percent = Math.round((e.loaded / e.total) * 100); progressbar.progressbar("value", percent); } }); // 上传完成处理 xhr.onload = function() { progressbar.fadeOut(300); // 这里添加上传成功后的逻辑 if(xhr.status === 200) { alert("上传成功"); document.getElementById("image_preview").src = "about:blank"; $("#files").val(""); // 清空文件选择框 } else { alert("上传失败,请重试"); } }; xhr.open("POST", "你的服务器上传接口地址"); xhr.send(formData); }
内容的提问来源于stack exchange,提问作者bandito40
相关产品推荐
相关产品推荐

