checked属性存在即选中,值无效;name大小写敏感需统一;js应设.checked而非setattribute;框架中defaultchecked与checked不可混用。

checked属性只看是否存在,不解析值
HTML中的默认选中行为,完全取决于checked属性是否**存在**,而不是它的值。写checked=""、checked="false"甚至checked="0",浏览器都当它已选中。真正“不选中”,就得彻底删掉这个属性。
-
<input type="radio" name="mode" value="dev" checked>→ 选中 -
<input type="radio" name="mode" value="prod" checked>→ 还是选中(别信字符串) -
<input type="radio" name="mode" value="test">→ 不选中(没写checked)
模板渲染或服务端拼接时,容易误把布尔逻辑转成字符串输出,比如生成checked="false",结果反而让按钮被默认选中——这是最常踩的坑。
name必须完全一致,大小写敏感
单选按钮的互斥性靠name分组实现,但这个分组对大小写、空格、下划线全敏感。哪怕只差一个字符,两个input就变成独立控件,可能同时带checked,提交时后端收到多个值。
- ✅ 正确:
<input name="theme">和<input name="theme"> - ❌ 错误:
<input name="Theme">和<input name="theme">(大小写不同) - ❌ 错误:
<input name="user preference">(含空格,部分后端解析失败)
建议统一用全小写+短横线,如user-preference;用document.querySelectorAll('input[type="radio"][name="theme"]')可快速验证是否全部命中同一组。
JS动态设置要改.checked,不是setAttribute
页面加载后想用JS切换默认选中项,必须操作element.checked这个DOM property,而不是setAttribute('checked', '')。后者只改HTML attribute,既不触发视觉变化,也不影响同组其他radio自动取消选中。
- ✅ 正确:
document.querySelector('input[name="size"][value="l"]').checked = true(自动清掉同组其他项) - ❌ 错误:
el.setAttribute('checked', 'checked')(无效,且不会取消同组其他checked) - ⚠️ 注意:单纯赋值
.checked = true不会触发change事件,依赖事件的业务逻辑(如联动显示)会失效;需额外el.dispatchEvent(new Event('change', { bubbles: true }))或直接调用el.click()
动态插入的元素(比如通过innerHTML添加),必须先挂载到DOM,再设置.checked,否则无效。
框架里别混用defaultChecked和checked
React/Vue等框架中,defaultChecked只在首次渲染时生效,之后由框架接管状态;而checked会让组件变成受控模式,必须配合onChange同步更新state。两者混用会导致状态脱钩、点击跳回原值、控制台报错“changing an uncontrolled input to be controlled”。
- React推荐:
<input type="radio" name="lang" value="zh" defaultchecked="{data.lang">(非受控) - React受控写法:
<input type="radio" name="lang" value="zh" checked onchange="{(e)"> setLang(e.target.value)} />(必须配onChange) - Vue中:
v-model绑定的变量初始值必须与某个value匹配,否则所有选项显示为未选中
SSR场景下,服务端渲染的defaultChecked或初始v-model值,必须和客户端hydration前的状态严格一致,否则会降级接管并导致UI闪烁。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











