select 多选必须加 multiple 属性,否则即使按 Ctrl/Cmd 也仅单选;预选中靠 option 的 selected 属性,JS 获取需用 selectedOptions 而非 value;后端接收须用 name="xxx[]" 命名。

select 多选必须加 multiple 属性
不加 multiple,哪怕按住 Ctrl 或 Cmd 点击,浏览器也只允许单选。这是最常被忽略的前提——<select> 默认是单选控件,和 UI 表现无关,是行为定义。
实操建议:
- 直接在
<select>标签里写multiple(布尔属性,无需赋值) - 可配合
size控制可见行数,比如size="4"显示 4 行选项,避免下拉展开;不设则默认显示 1 行+下拉箭头 - 移动端注意:iOS Safari 对
multiple支持有限,部分版本会降级为单选弹窗,需额外 JS 拦截或改用其他组件
预选中靠 option 的 selected 属性
不是给 <select> 设值,而是给内部每个 <option> 加 selected。浏览器加载时自动识别带该属性的项为已选状态。
常见错误现象:
立即学习“前端免费学习笔记(深入)”;
- 写了
value="xxx"但没加selected→ 不会预选 - 多个
<option>都写了selected→ 全部预选中(合法且常用) - 动态渲染时(如 Vue/React)用
selected={true}但未同步更新 DOM 属性 → 依赖框架绑定逻辑,纯 HTML 不适用
示例:
<select multiple size="4"> <option value="apple">苹果</option> <option value="banana" selected>香蕉</option> <option value="orange" selected>橙子</option> <option value="grape">葡萄</option> </select>
后端传值时 name 属性要带 []
如果表单提交到后端(比如 PHP、Python Flask),<select multiple> 提交的多个值默认会以同名覆盖方式发送,只收到最后一个。必须用数组式命名才能让服务端解析为列表。
实操建议:
- HTML 中写
name="fruits[]"(PHP 风格)或name="fruits"(Django/Flask 默认接受多值) - PHP 接收时用
$_POST['fruits']直接得到数组;Node.js 的urlencoded中间件也支持同名多值自动聚合成数组 - 不加
[]且后端没做多值解析 → 只拿到一个字符串,通常是最后选中的那个value
JS 获取/设置多选值要用 value 数组而非单个字符串
select.value 在多选场景下只返回第一个选中项的 value,不能反映全部状态。必须遍历 select.options 或用 select.selectedOptions。
推荐写法:
- 获取所有选中值:
[...select.selectedOptions].map(opt => opt.value) - 设置预选中(JS 动态):
option.selected = true,不能只改select.value - 清空所有选择:
select.selectedIndex = -1无效,得循环设option.selected = false或直接select.selectedOptions.forEach(opt => opt.selected = false)
兼容性注意:selectedOptions IE 不支持,如需兼容 IE9–10,改用 for (let i = 0; i < select.options.length; i++) { if (select.options[i].selected) ... }。
真正容易被忽略的是:预选中状态和用户交互后的值读取,走的是两套逻辑——HTML 层靠 selected 属性,JS 层靠 selectedOptions 集合。混用 value 读写会导致预期外的单值覆盖。



















