下拉列表未选时校验失败的根源在于占位项未设为disabled且selected。正确写法是:<option disabled selected>请选择</option>,后续选项value非空;JS校验应检查selectedIndex === 0 && options[0].hasAttribute('disabled')而非仅判空value。

下拉列表没选时触发校验失败
HTML 原生表单校验中,<select> 默认不会被 required 触发,除非它有至少一个带 value 的非空选项 —— 但很多人会加一个「请选择」的占位项,比如:
<select required><br> <option value="">请选择</option><br> <option value="a">选项A</option><br></select>这种写法在 Chrome/Firefox 中实际会通过校验,因为
value="" 被视为“已选择”,哪怕用户没主动点过。
让空选项不满足 required 的正确写法
必须把占位 <option> 标记为 disabled 且 selected,同时确保它没有 value 或 value="" 不参与提交。浏览器只会在所有可选选项(即未 disabled)都未被选中时才判定为未填写。
-
<option disabled selected>请选择</option>—— 关键:禁用 + 默认选中,且不设value - 后续每个真实选项必须有非空
value,例如<option value="us">美国</option> - 不要写
<option value="" disabled selected>,部分旧版 Safari 仍可能误判
JavaScript 手动校验时容易忽略的细节
用 JS 检查 select.value 是否为空,看似简单,但要注意:
-
select.value在未选中任何选项时返回空字符串"",但若第一个选项是<option value="">(未disabled),它也会返回""—— 这不是用户漏选,而是选了无效值 - 更稳妥的方式是检查
select.selectedIndex === 0 && select.options[0].hasAttribute('disabled'),判断是否卡在禁用占位项 - 如果用了
multiple,得用select.selectedOptions.length === 0,而不是看value
submit 事件中阻止默认行为的时机
别在 submit 里只靠 checkValidity() 就放行 —— 它对上述「禁用占位+非空选项」结构是有效的,但某些自定义组件或动态渲染的 select 可能绕过原生校验逻辑。
立即学习“前端免费学习笔记(深入)”;
- 显式调用
form.checkValidity()并监听invalid事件,比单纯读select.value更可靠 - 如果手动校验失败,记得
event.preventDefault(),否则表单仍会提交 - 注意:Chrome 92+ 对
required的select在首次聚焦后才激活校验,直接 submit 可能跳过提示,需配合reportValidity()
required 的实现细节,而不是「有没有写 required」本身。很多问题出在占位项没禁用,或者 JS 校验只盯 value 字符串而忽略了 DOM 状态。



















