原生 select[multiple] 存在跨平台兼容性问题:Windows/Linux 需 Ctrl、macOS 需 Command 多选,iOS Safari 直接降级为单选 Picker;JS 获取值须用 selectedOptions;表单提交需后端按数组接收;移动端建议改用 checkbox 或自定义组件。

Windows/macOS 多选键位差异必须显式提示
原生 select[multiple] 不会自动适配系统习惯,用户按错键就等于没多选:Windows/Linux 用户必须按住 Ctrl 点击单个选项切换状态,macOS 用户则必须按 Command;Shift 连续选择虽两者都支持,但只作用于当前可视区域内的连续项(不跨滚动)。常见错误是只写 <select multiple> 却不加任何说明——用户点一次就以为“选中了”,实际清空了之前所有选项。
建议在 label 旁或下拉框右侧加小字提示,例如:<span class="hint">按 Ctrl/Cmd 多选</span>。别依赖 tooltip 或 hover 提示,移动端根本触不到。
iOS Safari 会彻底忽略 multiple 属性
iOS Safari 不是“不支持”,而是主动降级:它直接无视 multiple,点击后弹出的是单选式全屏 Picker,不显示已选项、无法反选、也不响应键盘修饰键。这不是 bug,是 WebKit 的设计决策。
检测方式推荐用 @supports (-webkit-appearance: none) 配合 JS 判断样式能力,比 navigator.userAgent.includes('iPhone') 更可靠;真要支持 iOS 多选,必须放弃原生 select,改用 <div role="listbox" aria-multiselectable="true"> + 手动管理 aria-selected 状态。
立即学习“前端免费学习笔记(深入)”;
如果项目里 iOS 流量占比高,且多选是核心路径,别犹豫——从一开始就用 checkbox 组合模拟,或引入 tom-select 这类库(注意初始化时仍需传 multiple: true)。
JS 获取值别碰 value,必须用 selectedOptions
select.value 在 multiple 模式下永远只返回第一个选中项的 value 字符串,哪怕你选了十个。这是 DOM 规范强制行为,不是浏览器差异。
正确获取全部值的方法只有两个:
-
Array.from(select.selectedOptions).map(opt => opt.value)(推荐,语义清晰、现代浏览器全支持) -
Array.from(select.options).filter(opt => opt.selected).map(opt => opt.value)(仅当需兼容 IE11 时用)
注意:option 若没设 value,其值为 textContent,可能含空格或换行,建议 .trim() 后再使用。
表单提交时 name 重复发送,后端必须按数组接收
原生 select[multiple] 提交时,会把每个选中项作为独立参数发出,例如 tag=1&tag=3&tag=5。后端若只取第一个 tag,就只剩一个值。
PHP 中 $_POST['tag'] 默认是数组;Node.js 的 express.urlencoded({ extended: true }) 才能解析成数组;Laravel/Django 等框架更建议前端写成 name="tag[]",避免中间件解析歧义。
移动端不可靠这点常被忽略:安卓 Chrome 表现不一,有些机型无视觉反馈、无法取消已选;iOS 则完全走不通。所以只要业务逻辑强依赖多选结果,就别把它当默认方案——checkbox 组合或自定义下拉面板才是真实可用的路径。



















