radio 的 name 属性是互斥的唯一依据,浏览器仅通过完全相同的 name 值(区分大小写与空格)判定单选组,name 缺失或不一致会导致互斥失效,checked 仅控制初始状态且同组多 checked 时仅首个生效。

radio 的 name 属性是互斥的唯一依据
浏览器不看 class、id 或位置关系,只靠 name 值相同来判定一组单选框。只要两个 <input type="radio"> 的 name 属性值完全一致(包括大小写和空格),它们就自动形成互斥组:选中一个,其余同名 radio 会自动取消选中。
- 必须确保所有同组 radio 的
name字符串逐字相同,比如name="gender"和name="Gender"是两组 -
name不需要额外 JS 绑定或事件监听,这是原生行为 - 如果某 radio 没写
name,它就“游离”在任何组外,永远无法被其他 radio 影响
常见失效场景:name 值表面相同但实际不同
很多问题不是逻辑没写对,而是 name 看似一样,实则藏了隐形差异:
- 模板渲染时拼接出错,比如
name="user[role]"和name="user[role] "(末尾空格) - Vue/React 中用变量插值时未加引号或转义,导致生成
name=user.role(没引号 → 解析为属性名而非字符串) - 后端模板引擎(如 Jinja2、Thymeleaf)里变量为空,渲染成
name="",这组 radio 实际无效 - 使用
document.createElement('input')动态创建时,忘了设el.name = 'xxx',只设了value或id
checked 属性只控制初始状态,不破坏互斥逻辑
checked 是布尔属性,仅决定页面加载时哪个 radio 默认被选中。它不影响运行时互斥规则:
- 页面中可以有多个 radio 都写了
checked,但浏览器只让第一个生效,其余自动忽略 —— 这是规范行为,不是 bug - JS 修改
checked时,仍需保证目标元素属于该name组,否则不会触发同组取消逻辑 - 不要用
radio.checked = true强行“选中多个”,那只会让最后一个赋值生效,且前面的会被浏览器静默取消
<input type="radio" name="theme" value="light" checked> <input type="radio" name="theme" value="dark" checked> <input type="radio" name="theme" value="auto">上面代码加载后,只有第一个
light 会被选中,第二个 dark 的 checked 被忽略。
服务端接收时只拿到一个值,别漏处理
表单提交后,后端收到的只是该 name 对应的单个 value(如 theme=dark),不是数组:
立即学习“前端免费学习笔记(深入)”;
- 不要尝试按数组解析,比如 PHP 的
$_POST['theme'][]会报错或为空 - 如果没选任何 radio,该
name根本不会出现在 POST 数据里(不是null,是缺失) - 前端 JS 读取时用
document.querySelector('input[name="theme"]:checked')?.value最安全,避免遍历所有 radio
name 相同是唯一开关,但拼错、漏写、动态生成时少个引号,都会让这个开关彻底失灵。互斥看着简单,实际卡在细节里。



















