HOWTO · JavaScript

在 JavaScript 中處理 select 的 change 事件

使用 change 事件讀取 select 的值、處理多個下拉式選單,並區分使用者變更與程式設定的值。

本頁內容

如果要在使用者選擇其他選項時執行 JavaScript,請在 <select> 元素上監聽 change 事件,再從 event.target.value 讀取值並更新頁面。在 JavaScript 中,事件名稱是 changeonchange 是對應的 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,因此不適合直接讀取多個選項。

changeinput 與程式設定值的差異

<select> 而言,change 通常表示使用者確認了新的選擇。它與文字輸入的時機不同:對文字框而言,change 可能要等控制項失去焦點後才觸發。只有確實需要相應互動時才使用 input,不要假設兩個事件的時機完全相同。

使用 JavaScript 設定 select.value 會改變控制項,但不會自動派發使用者觸發的 change 事件。可以直接呼叫相同的更新函式,或在需要通知其他監聽器時派發事件:

select.value = "blue";
select.dispatchEvent(new Event("change", { bubbles: true }));

派發事件不會模擬真實使用者操作,也不會自動提交表單。仍應驗證值,並在伺服器端驗證不可信資料。新程式碼優先使用 addEventListener("change", ...);內嵌 onchange="..." 可以運作,但會把標記和行為混在一起,重複使用性較差。