checked属性仅在页面首次加载时生效,是HTML的一次性声明,不影响后续状态;DOM property(element.checked)与HTML attribute相互独立,:checked伪类仅响应property变化。

checked属性只管页面首次加载时的默认选中
HTML中的checked属性是**一次性声明**,不是响应式绑定。它只在DOM初始化阶段起作用:浏览器解析到<input type="checkbox" checked>,就将对应元素的checked property设为true;没写,就设为false。之后无论你改不改HTML源码里的checked attribute,都不会再影响控件状态。
常见错误现象:
- 用
element.setAttribute('checked', 'checked')试图“重新勾选”,但视觉无变化 - 服务端模板(如JSP)里写了
<input ... :>,但JS后续修改checkedproperty后,再刷新页面又回到服务端输出的状态——这不是bug,是预期行为
关键点在于:DOM property(element.checked)和 HTML attribute(element.getAttribute('checked'))是两个独立值。你可以让它们不一致,比如删掉attribute但保留element.checked = true,此时:checked伪类仍匹配,复选框仍显示为选中。
value属性与选中状态完全解耦
value属性只决定表单提交时的字符串值,跟是否勾选毫无关系。一个没勾选的<input type="checkbox" value="enabled">,提交时根本不会发任何数据;一旦勾选,就发name=value这对键值对。
立即学习“前端免费学习笔记(深入)”;
使用 PptxGenJS 和 Python 解析,将结构化的 HTML/CSS 幻灯片内容转换为原生、可编辑的 PowerPoint(.pptx)演示文稿。
容易踩的坑:
- 误把后端布尔值直接塞进
value,以为能控制选中:<input value="${user.enabled}">→ 没用,value不是checked - 手动在JS里同步
value和checked,比如el.value = el.checked ? '1' : '0'→ 这种逻辑纯属业务需要,浏览器不关心,也不强制要求 - 给多个同名checkbox设相同
value,结果提交时无法区分哪个被选中(尤其在name相同但没做分组处理时)
change事件监听的是property变化,不是attribute变化
用户点击、空格键切换、或脚本执行el.checked = true,都会触发change事件;但el.setAttribute('checked', '')不会触发——因为后者没改property。
所以:
- 永远用
addEventListener('change', handler),别用click,否则键盘操作漏掉 - 在Web Component里同步内部
<input>状态时,必须直接赋值this.#input.checked = this.checked,而不是操作attribute - SSR渲染后想初始化状态,优先用
el.toggleAttribute('checked', bool)或直接el.checked = bool,避免attribute和property错位
:checked伪类反映的是实时property值
CSS的:checked选择器不看HTML里有没有checked字样,只看element.checked === true是否成立。这意味着:
- JS执行
box.checked = true后,input:checked + label样式立刻生效 - 哪怕你用
box.removeAttribute('checked')清除了attribute,只要box.checked还是true,:checked照样匹配 - Safari对
:checked ~ .sibling(通用兄弟选择器)支持有限,若需兼容,改用:checked + .next(相邻兄弟)更稳妥
最易被忽略的一点:当服务端输出的HTML里多个同名radio都带checked,浏览器会按文档顺序取最后一个生效——这属于attribute解析阶段的行为,但property层面最终只有一个true,别指望靠多写几个checked来“覆盖”。


















