JavaScript input event 處理

starzodiac
4 min readDec 9, 2020

--

最近碰到 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>,所以沒辦法達成我要目的。⠀

解法:

  1. tag 設定不同的 id
  2. 利用 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()

詳情可以參考以下:

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

No responses yet

Write a response