上传错误文件重置file input后,再次上传新文件无响应问题
问题分析与修复方案
问题根源
- 事件绑定丢失:上传成功后通过
document.body.innerHTML = response.html替换了整个页面内容,原文件输入框被新元素替换,但新元素未绑定change事件,导致后续上传无响应。 - 额外触发change事件:错误处理时手动清空
fileInput.value会触发一次空文件的change事件,虽不影响功能,但可优化。
修复方案
1. 改用事件委托绑定事件
将事件绑定到不会被替换的父元素(如document),确保页面元素更新后事件依然有效。
2. 优化输入框清空逻辑
清空输入框时临时移除事件监听,避免触发额外的change事件,清空后重新绑定。
修改后的JS代码
// 事件委托绑定到document,确保页面替换后事件仍生效 document.addEventListener('change', function(event) { const fileInput = event.target; // 仅处理目标为transcribe-file的change事件 if (fileInput.id !== 'transcribe-file') return; if (fileInput.files.length > 0) { console.log(fileInput.value); let fileName = fileInput.value; const fileExtension = fileName.split('.').pop().toLowerCase(); const allowedExtensions = ['m4a', 'wav', 'mp3', 'mpeg', 'mp4', 'webm', 'mpga', 'ogg', 'flac']; if (!allowedExtensions.includes(fileExtension)) { const uploadField = document.querySelector('.upload-file-field-transcribe'); const originalLabelText = uploadField.innerHTML; uploadField.style.color = '#ad0f0f'; uploadField.textContent = 'Invalid file type. Please try again'; setTimeout(function() { uploadField.style.color = ''; uploadField.innerHTML = originalLabelText; }, 5000); // 临时移除事件监听,避免清空输入框触发额外change事件 const currentHandler = arguments.callee; document.removeEventListener('change', currentHandler); fileInput.value = ''; document.addEventListener('change', currentHandler); console.log(fileInput.value); return; } // 精准获取当前输入框所属表单 const form = fileInput.closest('form'); const xhr = new XMLHttpRequest(); const formData = new FormData(form); xhr.open('POST', form.getAttribute('action'), true); xhr.upload.onprogress = function(event) { if (event.lengthComputable) { let percentComplete = (event.loaded / event.total) * 100; let progressBar = document.getElementById('myBar'); if (progressBar) { progressBar.style.width = percentComplete + '%'; console.log('Upload progress: ' + percentComplete + '%'); } } }; xhr.onload = function() { if (xhr.status == 200) { console.log('Upload complete'); var response = JSON.parse(xhr.responseText); // 页面替换后事件委托依然有效,无需重新绑定 document.body.innerHTML = response.html; } else { console.error('Upload failed'); } }; xhr.send(formData); // 上传完成后清空输入框(可选) const currentHandler = arguments.callee; document.removeEventListener('change', currentHandler); fileInput.value = ''; document.addEventListener('change', currentHandler); } });
额外优化点
- 用
fileInput.closest('form')获取表单,比全局查询更精准,避免多表单场景出错。 - 增加进度条存在性判断,防止页面无进度条时报错。
内容的提问来源于stack exchange,提问作者tthheemmaannii
相关产品推荐
相关产品推荐

