全选状态直接由every()判断所有有效复选框是否全为checked,反选用forEach取反各框checked值,联动更新全选框需监听子项change并重算,过滤disabled项防干扰。
用 every() 实现全选/反选,核心不是“遍历判断”,而是**把“是否全选”这个状态,直接映射为“所有复选框是否都为 checked”这一布尔表达式**——逻辑干净,代码极少,且天然抗干扰。
一、全选状态 = 所有 checkbox.checked 是否全为 true
传统做法常维护一个额外的 isAllChecked 变量,手动同步;而 every() 让你直接从 DOM 状态实时推导:
- 获取所有目标 checkbox 元素(推荐用
querySelectorAll) - 转成数组(
Array.from或扩展运算符) - 调用
.every(cb => cb.checked)—— 任一未勾选即返回false
✅ 示例:
const checkboxes = Array.from(document.querySelectorAll('.item-checkbox'));<br>const isAllChecked = checkboxes.every(cb => cb.checked);二、反选只需一行:toggle 所有 checkbox 的 checked 状态
反选 ≠ 先判断再循环设值。更简洁的做法是:对每个 checkbox 直接取反其当前 checked 值:
- 无需预先读取当前全选状态
- 无需 if-else 分支控制逻辑
- 一次遍历,语义清晰:
cb.checked = !cb.checked
✅ 示例:
checkboxes.forEach(cb => cb.checked = !cb.checked);
三、联动更新“全选框”本身(关键细节)
主全选 checkbox(如 #select-all)必须与子项状态严格同步。每次子项变更或点击全选框时,都要重算并设置它的 checked:
- 监听所有子 checkbox 的
change事件(委托更优) - 事件回调中重新执行
every()判断,并赋值给全选框 - 全选框自身点击时,用
forEach反选全部子项,再同步自身状态
⚠️ 注意:不要在子项 change 中直接修改全选框的 checked 后再触发它的 change —— 容易引发无限循环。只读不写,或加防抖标记。
四、增强健壮性:过滤 disabled 和非 checkbox 元素
真实场景中,列表可能含 disabled 项或混入其他类型 input。安全写法是显式过滤:
- 用
filter(cb => cb.type === 'checkbox' && !cb.disabled)预处理 - 再对过滤后数组调用
every(),避免 disabled 项干扰判断 - 反选时也跳过 disabled 项(它们不应被 toggle)
✅ 推荐组合写法:
const validBoxes = checkboxes.filter(cb => cb.type === 'checkbox' && !cb.disabled);<br>const isAllChecked = validBoxes.length > 0 && validBoxes.every(cb => cb.checked);
(补充 length > 0 是防止空数组时 every() 返回 true 的“空真”陷阱)










