name属性必须唯一且严格匹配,否则单选按钮组失效或后端无法接收值;大小写、空格、不可见字符均导致不匹配;fieldset仅增强语义与可访问性,不改变name分组逻辑。

name属性必须不同,否则浏览器会把它们当成同一组
浏览器只看name值来判断哪些单选按钮属于同一组。如果两组本该独立的选项(比如“性别”和“语言偏好”)用了相同的name,用户点完“男”再点“英语”,前者就会自动取消——这不是 bug,是浏览器按规范执行互斥逻辑。
常见错误包括:
-
name="gender"和name="Gender"被视为两个不同组(大小写敏感) -
name="theme"和name=" theme"(开头有空格)也互不识别 - 复制粘贴时带了不可见 Unicode 字符(如零宽空格),导致看似相同实则不匹配
后端接收字段名必须和前端name完全一致
服务端(PHP/Node.js 等)靠name取值:$_POST['level'] 或 req.body.level。如果前端写的是name="user_level",而后端代码里写成userLevel或level,就拿不到值。
调试建议:
立即学习“前端免费学习笔记(深入)”;
- 打开浏览器开发者工具 → Network → 点击提交后的请求 → 查看 Payload 里有没有对应
name字段 - 没出现,说明没选中、不在
<form>内、或name拼错 - 出现但值为空,可能是所有 radio 都没设
checked且用户未手动选择
用fieldset + legend语义化区分视觉与逻辑分组
fieldset本身不影响单选逻辑,但它能明确告诉浏览器和屏幕阅读器:“这是一组相关选项”。对多组并存的表单,它让结构更清晰,也方便后续加 CSS 或 JS 控制。
示例:
<form>
<fieldset>
<legend>支付方式</legend>
<input type="radio" id="cash" name="payment" value="cash">
<label for="cash">现金</label>
<input type="radio" id="card" name="payment" value="card">
<label for="card">银行卡</label>
</fieldset>
<fieldset>
<legend>发票类型</legend>
<input type="radio" id="personal" name="invoice" value="personal">
<label for="personal">个人</label>
<input type="radio" id="company" name="invoice" value="company">
<label for="company">企业</label>
</fieldset>
</form>
这里name="payment"和name="invoice"天然隔离,fieldset只是强化语义和可访问性。
JavaScript 动态操作时别混淆checked属性和checked属性节点
JS 设置默认选中要用.checked = true,不是.setAttribute('checked', 'true')。后者在旧版 Safari 或某些动态插入场景下可能不触发表单状态更新。
批量控制某组 radio 时,得先按name筛选:
document.querySelectorAll('input[name="theme"]')<br> .forEach(radio => radio.checked = radio.value === 'dark');
注意:同一时刻只能有一个checked = true,否则行为不可靠;也不要依赖checked属性是否存在来判断是否选中——用.checked布尔值更准确。
最易被忽略的一点:name 值一旦写错,整个组就失效,但页面看起来完全正常——你得检查 Network 请求体或用 JS 手动查document.querySelector('input[name="xxx"]:checked')才能发现它根本没被选中。



















