multiple属性必须在HTML源码中声明为<select multiple>才生效,JS动态设置无效;size仅影响显示行数,与多选能力无关;selectedOptions是实时只读集合;iOS Safari完全忽略multiple交互语义,需提前降级。

multiple 属性必须写在 HTML 源码里才生效
浏览器引擎(Blink、WebKit、Gecko)在解析 HTML 时,只检查 multiple 是否作为**布尔属性存在**于起始标签中。它不读取值,也不响应 JS 动态设置——select.multiple = true 或 el.setAttribute('multiple', '') 都不会触发多选逻辑。
常见错误现象:
- 服务端模板漏掉
multiple,前端用 JS 补上,结果 Safari/Edge 仍为单选 - 写成
multiple="true"或multiple="1",部分旧版 WebKit 直接忽略该属性 -
multiple=""在 XHTML 解析模式下可能报错,不推荐
正确写法只有:<select multiple>。这是解析阶段唯一被识别的信号。
size 属性不影响多选能力,只影响渲染高度
size 是纯展示参数,和是否能多选完全无关。它的作用是在解析时告诉浏览器“这个 select 应该显示几行选项”,仅此而已。
立即学习“前端免费学习笔记(深入)”;
实操要点:
-
size="1":多数浏览器渲染为单行带滚动箭头,但仍是多选行为(需 Ctrl/Cmd) -
size="4":显示 4 行,用户一眼识别为列表框,可发现性高 -
size值 ≥ 总option数时,所有项平铺,无滚动条 - 父容器有
overflow: hidden或固定height,会裁掉超出部分——得看 computed style 确认实际可见行数
selectedOptions 是解析后 DOM 的实时反射,不是 JS 计算结果
浏览器在解析完 HTML 并构建 DOM 后,会为每个 select 元素生成一个 selectedOptions 属性,它是一个**实时 HTMLCollection**,反映当前哪些 option 节点的 selected 属性为 true。
关键事实:
-
select.value永远只返回第一个selectedOptions[0]?.value或空字符串,这是规范强制行为,不是 bug -
selectedOptions是只读、实时、动态更新的;遍历时不用防“中途变化”,因为 DOM 更新是同步的 - IE11 不支持
selectedOptions,回退方案是遍历select.options并检查opt.selected
iOS Safari 根本不解析 multiple 的交互语义
WebKit for iOS 在解析阶段就跳过了 multiple 的交互启用逻辑。它把 <select multiple> 当作普通 <select> 处理,点开直接调用原生单选 Picker。
这意味着:
- 无论你加没加
multiple、size、甚至onchange,iOS 上都看不到多选 UI - 不能靠 UA 检测后 patch 属性来修复,因为解析已结束,DOM 已定型
- 必须提前降级:用
matchMedia('(pointer: coarse)')或navigator.platform.includes('iPhone')切换为 checkbox 列表等自定义组件
最易被忽略的一点:很多人以为“加了 multiple 就万事大吉”,却没在 iOS 真机上点开验证过——那里根本没机会按 Ctrl。



















