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