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="..." 可以工作,但会把标记和行为混在一起,复用性较差。