JavaScript input event 處理
最近碰到 input file 處理完後,再按一次 button,會沒有反應的問題,簡單程式碼如下:
<head>
<script>
...var train_result_but = document.getElementById("train_result_open");
train_result_but.onclick = function(event) {
console.log("train_result_but click");
return;
}train_result_but.onchange = function(event) {
let fileData = event.target.files[0]; // 檔案資訊
console.log("train_result_but change");
if (fileData) {
console.log(fileData);
document.getElementById("file_name").innerHTML = fileData.name;
do_train_result_pick(event);
} else {
console.log("input file is empty");
}
}
</script>
</head><body>
<label id="train_result_open">請選擇需轉換之訓練結果檔案 (YYYMMDD-訓練結果*)<br><br/>
<input id="train_result_open" type="file"/></label>
<p id="file_name"> </p>
</body>
研究了一下,發現是 document 的內容沒有更新,所以沒有辦法觸發 onchange 事件,想說應該只要在每次處理完 onchange evnt 應該就可以:
document.getElementById("train_result_open").value = "";
BUT…事情並不是想像中的簡單…
因為我 <input> 跟 <label> 的 id 設成同一個(我被網路文章誤導了XD),getElementById 會去 DOM 拿到第一個設定的 object,也就是 <label>,所以沒辦法達成我要目的。⠀
解法:
- tag 設定不同的 id
- 利用 jQuery 來處理:
$('input[type="file"]').val('');
3. 純 JavaScript 的解法(據說是 ES6 以後才支援):
var bothElements = document.querySelector("[id='train_result_open']");
var oneElement = bothElements.querySelector("[type='file']");train_result_but.onchange = function(event) {
...
let bothElements = document.querySelectorAll("[id='train_result_open']");
let oneElement = Array.from(bothElements).find((node) => node.type === 'file');
oneElement.value = "";
}
比較特別的地方是 document.querySelectorAll 回傳的是 NodeList,這東西算是 array-like object,不算是 array,所以不能直接使用 array.find()
詳情可以參考以下: