单选框互斥依赖name属性完全一致(含大小写),应统一命名如payment-method;用change事件监听并获取e.target.value;联动字段初始隐藏用display:none,加载后需同步初始状态。

单选框 name 必须一致才能互斥选择
浏览器靠 name 属性识别一组单选框是否属于同一逻辑项。如果漏写或写错 name,点击不会取消其他选项,联动也就无从谈起。
常见错误是复制粘贴时只改了 id 和 value,忘了统一 name:
<input type="radio" name="plan" value="basic"> 基础版<br><input type="radio" name="plan" value="pro"> 专业版 <!-- ✅ 正确 --><br><input type="radio" name="PLAN" value="enterprise"> 企业版 <!-- ❌ name 大小写不一致,变成独立组 -->
- 所有同组单选框的
name值必须完全相同(包括大小写) - 建议用小写字母 + 连字符,如
payment-method,避免空格或特殊符号 -
value值应语义清晰、便于后端或 JS 判断,别用中文或含空格字符串
用 change 事件监听选中变化,别用 click
change 在用户真正切换选项后触发,且只在值实际改变时发生;click 可能在未切换时也触发(比如重复点已选中的项),导致逻辑错乱。
- 监听
document.querySelectorAll('input[name="plan"]')所有节点,统一绑定change - 在回调里用
e.target.value获取当前选中的值 - 不要依赖
checked属性轮询判断——既低效又容易漏掉初始状态
示例片段:
文章转信息图。将文章/笔记转化为手机可读的 HTML 信息图,自动匹配视觉风格。触发场景:文章转图、笔记转图、信息图、转小红书图、做张图、可视化这篇文章、文生图。
立即学习“前端免费学习笔记(深入)”;
document.querySelectorAll('input[name="plan"]').forEach(radio => {<br> radio.addEventListener('change', e => {<br> const selected = e.target.value;<br> if (selected === 'pro') {<br> document.getElementById('pro-fields').style.display = 'block';<br> } else {<br> document.getElementById('pro-fields').style.display = 'none';<br> }<br> });<br>});隐藏后续字段推荐用 display: none,而非 visibility: hidden
visibility: hidden 只隐藏视觉,元素仍占布局空间,可能导致表单错位或校验逻辑异常;而 display: none 彻底移出渲染流,更符合“条件显示”的语义。
- 初始 HTML 中就该把后续字段设为
style="display: none",避免页面闪动 - JS 控制时只改
style.display,不操作class(除非你已预设好 CSS 类) - 若需过渡动画,改用
opacity+pointer-events配合transition,但要额外处理表单控件禁用/启用
初始状态没选中时,联动字段应默认隐藏
很多页面加载后没默认选中任何单选框,但后续字段却意外显示了——这是因为 JS 没检查初始状态,只响应了后续的 change。
- 页面加载完立即执行一次状态同步:查哪个单选框
checked === true,再按其value显示对应区块 - 或者更稳妥:先统一隐藏所有联动区块,再根据当前选中项决定是否显示
- 注意表单重置(
<form>的reset事件)后也要重新同步,否则联动状态会脱节
容易被忽略的是:服务端渲染或框架(如 Vue/React)中,DOM 尚未就绪时就执行 JS,querySelector 返回 null。务必等 DOMContentLoaded 或使用 defer 脚本。


















