JS多文件上传:如何等待文件内容加载完成再启用保存按钮
解决方案
问题根源
文件内容读取是异步操作,你点击保存时部分文件还没完成读取,导致content为null;等待后读取完成,所以content有值。下面是针对性的解决实现:
1. 等待所有文件内容加载完成再执行后续操作
通过Promise封装每个文件的读取过程,用Promise.all等待所有文件读取完成后,再允许触发保存逻辑。
2. 控制保存按钮置灰状态
初始将按钮设为禁用状态,所有文件读取完成后再启用按钮。
修改后的完整代码
HTML部分
<input id="file" type="file" multiple style="width: 600px"> <button id="btn_save_file" class="w2ui-btn" onclick="get_save_file()" disabled>Save</button>
注:补充了
type="file"和multiple属性以支持多文件选择,初始给按钮加disabled置灰。
JavaScript部分
// 存储读取完成的文件数据 let processedFiles = []; // 监听文件选择事件 document.getElementById('file').addEventListener('change', function(e) { const selectedFiles = e.target.files; if (!selectedFiles.length) return; // 重置状态 document.getElementById('btn_save_file').disabled = true; processedFiles = []; // 为每个文件创建读取Promise const readTasks = Array.from(selectedFiles).map(file => { return new Promise((resolve, reject) => { const reader = new FileReader(); // 根据需求选择读取方式:readAsDataURL(转base64)/ readAsText(读文本) reader.readAsDataURL(file); reader.onload = function(event) { // 组装符合你需求的文件数据结构 const fileData = { name: file.name, size: file.size, type: file.type, content: event.target.result }; processedFiles.push(fileData); resolve(fileData); }; reader.onerror = () => reject(`读取文件${file.name}失败`); }); }); // 等待所有文件读取完成 Promise.all(readTasks).then(() => { // 启用保存按钮 document.getElementById('btn_save_file').disabled = false; // 同步到原代码的data属性,保持逻辑兼容 $('#file').data('selected', processedFiles); }).catch(err => { console.error(err); // 读取失败可添加用户提示逻辑 }); }); window.get_save_file = function () { const dataFiles = $('#file').data('selected'); console.log(dataFiles); insertFile(dataFiles); } function insertFile(dataFiles) { $.ajax({ url: 'data/UploadFile', type: 'POST', dataType: 'json', data: { request: JSON.stringify(dataFiles) } }); }
关键说明
- 异步读取控制:用
Promise.all确保所有文件的FileReader异步操作完成后,才解锁保存功能。 - 按钮状态管理:通过
disabled属性严格控制按钮可用性,只有所有文件读取完成后才允许点击。 - 读取方式选择:根据后端接口需求,可将
readAsDataURL替换为readAsText(文本文件场景)或其他FileReader读取方法。
内容的提问来源于stack exchange,提问作者PMT
相关产品推荐
相关产品推荐

