HOWTO · JavaScript
在 JavaScript 中處理 select 的 change 事件
使用 change 事件讀取 select 的值、處理多個下拉式選單,並區分使用者變更與程式設定的值。
本頁內容
如果要在使用者選擇其他選項時執行 JavaScript,請在 <select> 元素上監聽 change 事件,再從 event.target.value 讀取值並更新頁面。在 JavaScript 中,事件名稱是 change;onchange 是對應的 HTML 屬性或事件處理器屬性。
監聽單選下拉式選單的 change 事件
為控制項加入關聯的標籤和穩定的 id,並在元素存在後註冊監聽器。監聽器會收到 Event,而 event.target 就是值發生變更的 select。
<label for="color">Choose a color:</label>
<select id="color" name="color">
<option value="">Choose one</option>
<option value="red">Red</option>
<option value="blue">Blue</option>
</select>
<p id="message" aria-live="polite"></p>
const color = document.querySelector("#color");
const message = document.querySelector("#message");
color.addEventListener("change", (event) => {
const value = event.target.value;
message.textContent = value ? `You chose ${value}.` : "Choose a color.";
});
使用者選擇 blue 後,段落會變成 You chose blue.。option 的 value 是傳給程式的資料值;如果沒有 value 屬性,就會使用 option 的文字。保留與控制項關聯的 label,方便鍵盤使用者和輔助技術識別控制項。
直接讀取選取的 option
對單選控制項而言,select.value 會傳回第一個選取 option 的值。 select.selectedIndex 會傳回它的位置,而 select.options[select.selectedIndex] 可以存取 option 元素和顯示文字。為佔位 option 設定 value="",即可判斷使用者尚未選取真正的值:
color.addEventListener("change", (event) => {
const select = event.target;
const option = select.options[select.selectedIndex];
message.textContent = select.value
? `You chose ${option.textContent}.`
: "Choose a color.";
});
如果應用程式需要穩定的識別碼,不要把顯示文字當作識別碼。例如 option 可以顯示 United States,但提交值是 us。
處理多個 select 元素
當多個控制項共用 class 或父容器時,可以使用一個監聽器。事件委派也適合之後動態加入的控制項:
<label>Color <select class="filter"><option value="red">Red</option><option value="blue">Blue</option></select></label>
<label>Size <select class="filter"><option value="small">Small</option><option value="large">Large</option></select></label>
<p id="filters" aria-live="polite"></p>
const filters = document.querySelector("#filters");
document.addEventListener("change", (event) => {
if (!event.target.matches("select.filter")) return;
filters.textContent = `${event.target.name || "Filter"}: ${event.target.value}`;
});
對允許多選的控制項,加入 multiple 屬性並讀取 selectedOptions,不要只讀取 value:
const values = [...select.selectedOptions].map((option) => option.value);
value 只代表第一個選取的 option,因此不適合直接讀取多個選項。
change、input 與程式設定值的差異
對 <select> 而言,change 通常表示使用者確認了新的選擇。它與文字輸入的時機不同:對文字框而言,change 可能要等控制項失去焦點後才觸發。只有確實需要相應互動時才使用 input,不要假設兩個事件的時機完全相同。
使用 JavaScript 設定 select.value 會改變控制項,但不會自動派發使用者觸發的 change 事件。可以直接呼叫相同的更新函式,或在需要通知其他監聽器時派發事件:
select.value = "blue";
select.dispatchEvent(new Event("change", { bubbles: true }));
派發事件不會模擬真實使用者操作,也不會自動提交表單。仍應驗證值,並在伺服器端驗證不可信資料。新程式碼優先使用 addEventListener("change", ...);內嵌 onchange="..." 可以運作,但會把標記和行為混在一起,重複使用性較差。