必须监听change事件而非click,因change能覆盖鼠标、空格键、tab+enter及屏幕阅读器等所有状态变更路径;click则无法捕获键盘操作且移动端易误触发。

直接操作 checked 属性,别用 setAttribute('checked', ...) 或模拟点击 —— 后者不触发表单状态更新,也不兼容键盘操作。
为什么必须用 change 事件监听全选框
用户可能用空格键、回车键或屏幕阅读器切换复选框,click 事件完全捕获不到这些行为。只有 change 能覆盖所有状态变更路径。
- 监听
click:移动端双击易误触发两次,键盘操作彻底失效 - 监听
change:无论鼠标、空格、Tab+Enter,全部可靠响应 - 全选框自身也要绑定
change,不能只靠初始渲染
querySelectorAll 选目标复选框时怎么避免误伤
表格里常有多个复选框组(比如“操作列”“状态列”“全选框”),用宽泛选择器会批量改错对象。
- 错误写法:
document.querySelectorAll('input[type="checkbox"]')—— 拿到页面所有 checkbox,包括搜索过滤控件、分页开关等 - 推荐写法:
document.querySelectorAll('tbody input[name="item_id"]:not(#select-all)')—— 锁定数据行、按 name 分组、排除全选框自身 - 如果表格支持服务端分页,
tbody内只含当前页 DOM,这个范围天然安全;若用虚拟滚动,得换数据驱动方案,不能依赖 DOM 查询
怎么让全选框正确显示 indeterminate 状态
HTML 不自动维护半选状态,必须手动设 indeterminate,而且顺序不能错:先设 false,再设 true,否则部分浏览器不刷新视觉。
- 每次任一数据复选框
change时,都要重新统计:const checked = document.querySelectorAll('input[name="item_id"]:checked').length;const total = document.querySelectorAll('input[name="item_id"]').length; - 然后判断:
→checked === 0:全选框checked = false,indeterminate = false
→checked === total:全选框checked = true,indeterminate = false
→ 其他情况:先selectAll.indeterminate = false,再selectAll.indeterminate = true - 漏掉重置
indeterminate是最常见 UI 错乱原因 —— 它不会随checked自动清除
真正麻烦的不是勾选动作本身,而是当表格叠加了搜索、排序、分页或禁用项时,DOM 顺序和业务数据已脱钩;此时还依赖 rows[i].dataset.id 取值,十有八九提交错 ID。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











