radio互斥仅由name属性值完全一致决定,大小写、空格敏感;未选中的radio不提交;js获取须用:checked伪类并判空。

radio互斥只看name属性,其他都无效
浏览器判断单选按钮是否互斥,**只依赖name属性值是否完全一致**——大小写敏感、空格敏感、前后缀差异都会导致分组失败。哪怕所有按钮都在同一个<form></form>里,只要name="gender"和name="Gender"并存,它们就是两组独立控件,能同时被选中。
常见错误包括:
- 复制粘贴时漏改
name,比如从name="plan"复制出name="plan2" - 用模板引擎动态拼接
name却忘了统一上下文,如name="user[{{i}}][level]"生成了不同索引 - 在SPA中重复挂载组件,导致同一页面出现多组同名
name="theme",但逻辑上本应隔离
修复方式很简单:打开开发者工具,选中任意一个radio,看name属性值;再点另一个,确认值是否一字不差。
未选中的radio根本不会提交,后端必须处理字段缺失
表单原生提交(method="POST")或用new FormData(form)收集数据时,**未选中的<input type="radio">完全不出现在数据中**。这不是遗漏,是HTML规范行为。例如一组name="status",用户没点任何选项,后端收到的请求体里压根没有status这个键。
这意味着:
- 后端不能假设字段一定存在,需显式检查
status是否在请求参数中 - 不能靠“接收不到值就设默认值”,因为这掩盖了用户漏选问题
- 若需必选,必须加
required属性,且只能加在同组任意一个radio上(加多个无意义)
FormData.get('status')会返回空字符串""而非null,但原生submit时该字段直接消失——两者行为不一致,别混用判断逻辑。
JS获取选中值必须带:checked伪类,否则取到的是第一个
用document.querySelector('input[name="mode"]')拿到的永远是DOM中第一个匹配的元素,不管它有没有被选中。真正安全的方式是强制限定状态:document.querySelector('input[name="mode"]:checked')。
注意几个关键点:
- 返回
null表示当前没选中任何项,必须判空,否则调.value会报Cannot read property 'value' of null - 如果页面有多个表单都用了
name="size",这个选择器会跨表单找——要限定范围,改用formEl.querySelector('input[name="size"]:checked') - 不要用
querySelectorAll遍历再判断checked,性能差且易漏掉动态插入的节点
简明写法:const val = document.querySelector('input[name="role"]:checked')?.value || '',但前提是业务允许空值。
checked属性不是开关,而是初始状态声明
checked是HTML布尔属性,只用于声明**初始渲染时哪个选项该被选中**。它不是响应式开关:JS修改el.checked = false能取消选中,但把另一个radio设为checked = true时,浏览器会自动清掉同组其他checked——这个互斥动作由浏览器控制,不是JS触发的。
容易踩的坑:
- 写
checked="false"或checked="",浏览器全当true处理,等价于checked - 在React/Vue中误用
defaultChecked去控制运行时状态,实际应该用受控模式+value/v-model - 以为设置了
checked就能让后端“默认接收”,其实没选中时字段照样不提交
动态设置推荐做法:先用document.querySelectorAll('input[name="pref"]')清空全部checked,再对目标项赋值true,避免残留状态干扰。
name属性的拼写一致性、字段缺失的后端校验、:checked伪类的强制使用——这三点漏掉任一,都可能让看似简单的单选逻辑在线上突然失效。尤其在多人协作或老项目迭代中,name值常被当作“小细节”忽略,结果调试半天才发现是大小写不一致。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











