type=file输入框二次选择相同文件时change事件不触发问题
解决File Input重复选择同一文件不触发Change事件的问题
问题原因
浏览器触发file input的change事件的前提是选中的文件列表发生变化。如果用户重复选择同一文件,浏览器会判定文件路径没有改变,因此不会触发change事件。
解决方案
每次处理完文件上传逻辑后(或触发文件选择框之前),将file input的value属性重置为空字符串。这样浏览器会把后续的选择视为新操作,即使文件相同也会触发change事件。
修改后的代码
JavaScript代码
function readURL(file) { return new Promise(function(resolve, reject) { let fr = new FileReader(); fr.onload = function() { resolve(fr.result); } fr.onerror = function() { reject(fr); } fr.readAsDataURL(file); }); } const fileInput = document.querySelector("#file"); fileInput.addEventListener("change", function(event) { let files = event.currentTarget.files; let readers = [] if (!files.length) return; for (let i=0; i<files.length; i++) { readers.push(readURL(files[i])); } readers.reverse(); Promise.all(readers) .then(function(values) { values.forEach(item => { let image = document.createElement("img"); image.className = "imgs"; image.src = item; document.querySelector("#messages").appendChild(image); }); // 处理完成后重置input的value fileInput.value = ""; }) .catch(function(err) { console.log(err); // 出错时也重置value,避免影响后续操作 fileInput.value = ""; }); }, false); // 按钮点击事件(替换原内联事件) document.querySelector("#btn").addEventListener("click", function() { fileInput.click(); });
HTML代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="style.css"> <script src="script.js" defer></script> <title>Document</title> </head> <body> <div class="contacts"></div> <div> <div id="messages"> </div> <div class="interact"> <div id="btn"> + </div> </div> </div> <input type="file" accept="image/*" id="file" multiple> </body> </html>
CSS代码(保持不变)
body { width: 100vw; height: 100vh; margin: 0; display: grid; grid-template-columns: 1fr 4fr; grid-template-rows: 100vh; overflow: hidden; } .contacts { grid-column: 1 / span 1; background-color: darkslategray; } body > div { grid-column: 2 / span 2; grid-template-rows: 6fr 1fr; display: grid; grid-template-rows: 6fr 1fr; } #messages { padding: 0 20px 10px 0; display: flex; flex-direction: column-reverse; align-items: flex-end; overflow-x: hidden; overflow-y: scroll; } #text { background-color: brown; padding: 3px 5px; } .interact { background-color: darkgray; display: flex; justify-content:center; align-items: center; } #btn { background-color: cadetblue; width: 50px; height: 50px; display: flex; justify-content: center; align-items: center; font-size: 30px; font-weight: bold; border-radius: 50%; cursor: pointer; } .imgs { max-height: 300px; }
说明
- 推荐在
change事件处理完成(成功/失败)后重置value,确保无论操作结果如何,都能重置input状态,不影响后续选择。 - 重置
value为空字符串不会干扰文件读取逻辑,因为事件触发时已经获取了完整的files列表。
内容的提问来源于stack exchange,提问作者Konstei
相关产品推荐
相关产品推荐

