这是购物车全选的经典逻辑:顶框管所有子框、子框反过来管顶框(用 every 判断是不是全选了)、反选、实时数选了几个。核心就一个属性:复选框的 .checked(true 打勾 / false 没打勾)。
已选中 0 件商品
勾一勾: 顶框管子框、 子框反推顶框, 下面同步代码与计数。
// 抓到顶框
let allCheck = document.getElementById('allCheck');
// 把所有子框抓出来
let itemList = document.querySelectorAll('.item');
// 顶框一勾或取消就跑
allCheck.addEventListener('change', function () {
// 从第 0 个子框挨个走
for (let i = 0; i < itemList.length; i++) {
// 每个子框都跟顶框走
itemList[i].checked = allCheck.checked;
}
// 打出来看看:true 是全勾
console.log('顶框状态', allCheck.checked);
});
// 给每个子框都绑一遍
for (let i = 0; i < itemList.length; i++) {
// 这次轮到的子框
let oneItem = itemList[i];
// 某个子框一改就跑
oneItem.addEventListener('change', function () {
// 先假设全勾
let allChecked = true;
// 挨个检查
for (let j = 0; j < itemList.length; j++) {
// 发现有一个没勾
if (!itemList[j].checked) {
// 那就不是全勾
allChecked = false;
// 不用再看后面的了
break;
}
}
// 把结果写回顶框
allCheck.checked = allChecked;
// 打出来看看
console.log('是不是全勾', allChecked);
});
}
如果你用错方法判断全选,顶框状态会不对。记住用 every——它是"每一个都满足才 true",正好表达"全部打勾"。
// 点反选按钮
reverseBtn.addEventListener('click', function () {
// 挨个走每个子框
for (let i = 0; i < itemList.length; i++) {
// 打勾变不打、不打变打
itemList[i].checked = !itemList[i].checked;
}
});
// 数一下选了几个
function updateCount() {
// 先从 0 开始数
let num = 0;
// 挨个看每个子框
for (let i = 0; i < itemList.length; i++) {
// 如果这个勾上了
if (itemList[i].checked) {
// 计数器加一
num = num + 1;
}
}
// 把数字显示出去
count.textContent = num;
// 打出来看看数对没
console.log('已选', num);
}
① 用在哪:购物车全选、批量操作、勾选审核。
② 常见坑:子框联动顶框判断写错;反选后顶框不同步。
③ 怎么解决:用 Array.every 判断是否全选;反选后重新同步顶框和计数。
| API | 作用 | 参数 | 返回值 | 代码示例 |
|---|---|---|---|---|
| 元素.checked | 读/改打没打勾 | true/false | 布尔 | all.checked = true; |
| addEventListener('change') | 勾选变化时触发 | 函数 | 无 | box.addEventListener('change', fn); |
| 循环遍历子框 | 逐个同步勾选状态 | for 循环 | 无 | for (let i = 0; i < list.length; i++) list[i].checked = true; |