先记住这个答案
<select multiple> 的 value 属性在 DOM 里只返回第一个被选中的 <option> 的值。如果没有选中任何项,value 是空字符串。想拿到所有选中项,要用 select.selectedOptions,它返回一个包含所有选中 <option> 元素的 HTMLCollection。
value只返回第一个选中项selectedOptions返回全部选中项集合- 表单提交时同名字段会发送多次
FormData.getAll()一次取回数组
用代码看清楚 value 和 selectedOptions 的区别
假设一个多选列表里选中了「苹果」和「香蕉」两项,直觉上 value 应该返回两个值,但实际只有一个。
<form id="fruit-form">
<select id="fruits" multiple name="fruit">
<option value="apple" selected>苹果</option>
<option value="banana" selected>香蕉</option>
<option value="cherry">樱桃</option>
</select>
</form>
<script>
const sel = document.getElementById('fruits')
// 只拿到第一个选中项
console.log(sel.value) // "apple"
// 拿到全部选中项
const vals = Array.from(sel.selectedOptions, option => option.value)
console.log(vals) // ["apple", "banana"]
</script>selectedOptions 是只读的实时集合。用户改了选择,集合会自动更新,不需要手动刷新。
另一种老写法是遍历 select.options,逐个检查 option.selected 是否为 true。效果一样,但代码更长。
表单提交时多选值怎么发送
用表单直接提交时,每个选中项都会作为独立的键值对发送。比如选了苹果和香蕉,请求体里会出现 fruit=apple&fruit=banana,同一个 name 出现两次。
FormData 取回数组JavaScriptconst form = document.querySelector('#fruit-form')
const data = new FormData(form)
// get() 只返回第一个值
console.log(data.get('fruit')) // "apple"
// getAll() 返回全部值的数组
console.log(data.getAll('fruit')) // ["apple", "banana"]后端如何解析重复的 fruit 键取决于框架和配置,不能假定一定合并成数组。前后端应约定“一个键可出现多次”,在前端用 FormData 预处理时则用 getAll(),否则 get() 只能拿到第一个。
在筛选器里做“标签多选”时,先约定无选中项代表什么:有些接口把缺少 fruit 键解释成“不过滤”,有些解释成“空结果”。原生提交在没有选项被选中时不会凭空发送一个空数组,前端若要表达“用户明确清空选择”,需要和后端约定额外字段或请求结构。脚本读取时,selectedOptions 的顺序通常按选项在 DOM 中的顺序,而不是用户点击先后;若业务需要点击顺序,要另行记录。
selectedOptions 是实时集合,保留它的引用后,用户选择一变,集合内容也跟着变。若代码要比较“提交前”和“提交后”两次选择,应该在各时点把值复制成数组,而不是保存同一个集合对象。select.value 在没有选中项时返回空字符串,这和“选中了一个值恰好为空字符串的选项”容易混淆;要判断是否真有选中项,查看 selectedOptions.length。
容易答错的地方
- 以为
value能返回多个值 - 这是最常见的误解。不管选了几项,
value永远只有一个字符串。多选列表的value和单选列表行为完全一样,只看第一个选中的<option>。 - 忘了
selectedOptions是 HTMLCollection 不是数组 selectedOptions没有map、filter这些数组方法。要当数组用需要先转换,用Array.from()或展开运算符[...sel.selectedOptions]。
面试官还会怎么问?
如果一个选项都没选,value 返回什么?
返回空字符串 ""。selectedOptions 返回一个长度为 0 的空集合。
用 JavaScript 怎么设置多个选中项?
不能通过给 value 赋值来选多项。要遍历 select.options,把目标项的 selected 设为 true。比如 select.options[1].selected = true。
React 里怎么处理多选 <select>?
React 的 <select multiple> 通过 value 属性接受一个数组,比如 value={['apple', 'banana']}。onChange 事件里同样要从 e.target.selectedOptions 读取所有选中值,和原生 DOM 的方式一样。
参考资料
示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。