单选按钮互斥靠的是 name 属性相同,不是 id 或 class;name 必须完全一致(含大小写和空格),否则视为不同组;value 决定提交值,需显式设置且避免中文或空格;无 checked 时字段不提交,服务端需检查字段是否存在。

单选按钮互斥靠的是 name 属性相同,不是靠 id 或 class
浏览器只认 name 相同的 <input type="radio"> 为一组,同一时刻只能选中其中一项。哪怕它们分散在不同 <form> 里、甚至不在同一个表单内,只要 name 值完全一致(包括大小写和空格),就强制互斥。
常见错误是给每个单选按钮设了不同 name(比如 name="option1"、name="option2"),结果点来点去都能选——这不是 bug,是预期行为,因为它们根本不在同一组里。
-
name必须字符串完全相等,name="gender"和name="Gender"是两组 - 不要用动态生成的随机
name(如带时间戳或索引),否则组关系就断了 -
id可以各不相同(也必须不同),用于关联<label>,不影响互斥逻辑
value 决定提交时发送什么,不是显示文本
用户看到的是 <label> 里的文字,或者 label 的 for 属性指向的元素内容。真正被表单提交或 JS 读取的是 value 属性值。
如果漏写 value,大多数浏览器会默认提交空字符串 "",容易导致后端收不到有效标识。
立即学习“前端免费学习笔记(深入)”;
- 务必为每个
<input type="radio">显式设置有意义的value,比如value="male"、value="female" - 避免用中文或含空格的
value(如value="男"),URL 编码可能出问题;优先用英文小写+下划线 - JS 获取选中项:用
document.querySelector('input[name="gender"]:checked')?.value,注意空值判断
没有默认选中项时,提交会丢失该字段
如果一组单选按钮都没加 checked,表单提交时,整个 name 字段根本不会出现在请求数据里(不是 null,是压根不传)。这对必填项是严重隐患。
- 服务端不能假设该字段一定存在,要主动检查 key 是否在 POST/GET 数据中
- 前端可加
required属性触发浏览器原生校验,但仅当所有 radio 在同一<form>内才生效 - 初始化 JS 状态时,别只依赖 DOM 是否有
checked,最好同步维护一个变量记录当前选择
跨表单或 Shadow DOM 场景下 name 仍有效,但 JS 查询要小心
name 的互斥作用域是全局文档级的,哪怕 radio 分布在多个 <form> 中,或嵌套在 Web Component 的 Shadow DOM 里,只要 name 相同,点击依然互斥。
但 JS 查询会受作用域限制:document.querySelectorAll('input[name="theme"]') 查不到 Shadow DOM 内部的节点;而 shadowRoot.querySelectorAll('input[name="theme"]') 又查不到外部的。
- 若需统一管理状态,建议用事件委托监听
change,再通过e.target.name归类处理 - 避免直接依赖
querySelectorAll结果长度判断是否“有选项”,因为可能分布在不同根节点 - 服务端永远以实际收到的
value为准,不反推“未提交 = 未选”,而是当作缺失字段单独处理



















