name属性不一致是单选按钮多选的根本原因,浏览器仅通过name字符串字面量匹配分组,大小写、空格、符号差异均导致分组失败;value重复不影响互斥但引发后端歧义;JS手动设置checked可能绕过原生互斥逻辑。

name属性不一致是根本原因
多个单选按钮同时被选中,几乎全是name值不统一导致的。浏览器只靠name字符串字面量匹配来分组,大小写、空格、下划线/短横线差异都会让它们变成不同组。比如name="status"和name="Status"就是两组,互不影响。
常见错误包括:
- 复制粘贴时漏改
name,如:<input type="radio" name="plan1">和<input type="radio" name="plan2"> - 前后端约定名不一致,后端期待
user_role,前端写了role - 模板渲染时变量拼错,比如
name="{{ group_name }}"在某次循环里没正确赋值
value重复不会导致多选,但会引发后端歧义
value重复本身不会破坏互斥逻辑——只要name相同,浏览器仍只允许选一个。但它会让服务端无法区分用户意图:两个value="on"的选项被选中时,提交的都是name=on,后端收不到有效语义。
务必确保同name下的每个value唯一且有意义:
立即学习“前端免费学习笔记(深入)”;
文章转信息图。将文章/笔记转化为手机可读的 HTML 信息图,自动匹配视觉风格。触发场景:文章转图、笔记转图、信息图、转小红书图、做张图、可视化这篇文章、文生图。
- 用
value="yes"/value="no",别用value="true"/value="false"(易与布尔解析混淆) - 避免空格或特殊字符,如
value="VIP member"应改为value="vip_member" - “无选项”也要显式定义,如
value=""或value="none",并配合required慎用
JavaScript手动设置checked可能绕过原生互斥
直接操作checked = true不会触发浏览器对同组其他项的自动取消逻辑——它只改当前元素状态。如果目标name不一致,或你忘了清掉旧选项,就会留下多个checked。
安全做法是:
- 优先用原生机制:确保
name一致,让浏览器自己管互斥 - 若需 JS 控制默认选中,只设一次:
document.querySelector('input[name="mode"][value="auto"]').checked = true - 绝对不要遍历所有 radio 手动设
checked=false再设新项——这既冗余又易出竞态
禁用/隐藏不等于解除分组关系
把某个input[type="radio"]设为disabled或display: none,只是让它不可交互或不可见,它仍在原name组内。如果此时其他同name项被选中,该禁用项的checked状态仍会被浏览器维护(虽然不提交),DOM 中也依然存在。
这意味着:
- 禁用项的
checked属性可能为true,但它不会出现在表单数据中 - 用
querySelectorAll('input[name="x"]:checked')仍可能拿到它,需额外过滤:not(:disabled) - 动态启用时,若之前被设为
checked,它会立刻生效,造成意外选中
name分组发生在 HTML 解析阶段,跟 JS 是否执行、CSS 是否加载、元素是否可见完全无关。哪怕你用 JS 把整个fieldset移除了,只要原始 HTML 里name写错了,页面一加载就已注定多选失效。


















