应监听表头复选框的change事件而非click,以兼容点击、空格键及屏幕阅读器;用event.target.checked获取实时状态,批量操作时统一加class如.row-checkbox并直接赋值checked属性;反选需逐个翻转每行状态;indeterminate状态须手动设置。

监听表头复选框的 change 事件,不是 click
用户点一下、空格键切换、屏幕阅读器触发,都应响应——change 才是语义正确且兼容性最稳的事件。用 click 会漏掉键盘操作,也容易在移动端误触未生效。
实操建议:
- 给表头复选框加明确标识,比如
id="check-all"或class="js-check-all" - 用
document.querySelector("#check-all").addEventListener("change", ...)绑定 - 别读
getAttribute("checked")——它返回的是 HTML 初始值,不是当前勾选状态;要用event.target.checked
批量设置行复选框用 querySelectorAll(".row-checkbox"),别遍历 tr
常见错误是写 table.querySelectorAll("tr") 再逐个找 input[type="checkbox"],这样既慢又脆弱:任意加个 div 包裹、换种 DOM 结构,逻辑就崩。
实操建议:
- 每行复选框统一加 class,如
class="row-checkbox",不依赖位置或嵌套层级 - 用
document.querySelectorAll(".row-checkbox")一次性拿到全部目标元素 - 赋值时直接设
cb.checked = event.target.checked,不是setAttribute("checked", "...")——后者只改属性,不更新 DOM 状态和 CSS 伪类
反选不能只取反表头的 checked 值
全选状态下点“反选”,确实该全不选;但若当前是部分勾选(比如 10 行里勾了 3 行),再点反选,就得把这 3 行变未勾、剩下 7 行变已勾——这时候必须逐个翻转每行状态,不能只靠 !header.checked 一刀切。
实操建议:
- 反选逻辑里遍历所有
.row-checkbox,对每个执行cb.checked = !cb.checked - 翻转前先检查
cb是否存在,避免Cannot set property 'checked' of null报错 - 如果某行 checkbox 是
disabled,记得跳过或按需处理,别强行赋值
indeterminate 状态要手动设,否则部分选中不显示
当用户手动勾选/取消某些行后,表头复选框应该呈现“中间横线”态(即 indeterminate),表示非全选非全不选。这个状态浏览器不会自动推断,必须 JS 手动控制。
实操建议:
- 每次行复选框
change后,统计已勾数量:const checked = document.querySelectorAll(".row-checkbox:checked").length - 设
headerCb.indeterminate = (checked > 0 && checked ,注意先设 <code>indeterminate = false再设checked,否则可能残留 - 别忘了同步更新
headerCb.checked:全勾则true,全空则false,否则保持indeterminate
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











