表格部分:
<div>
<table>
<thead>
<tr>
<!-- 注意不要把class和id写混了 -->
<th><input type="checkbox" id="j_cbAll"></th>
<th>商品</th>
<th>价钱</th>
</tr>
</thead>
<tbody id="j_tb">
<tr>
<td><input type="checkbox"></td>
<td>苹果</td>
<td>100</td>
</tr>
<tr>
<td><input type="checkbox"></td>
<td>雪梨</td>
<td>100</td>
</tr>
<tr>
<td><input type="checkbox"></td>
<td>橘子</td>
<td>100</td>
</tr>
<tr>
<td><input type="checkbox"></td>
<td>香蕉</td>
<td>100</td>
</tr>
</tbody>
</table>
</div>
我的思路:全选简单,点击总按钮的时候给子按钮遍历,一一勾选。
然后设置子按钮的点击事件,每点击一次就遍历一次子按钮,看看有没有checked值为false的,如果有,就把总按钮也设置成false,这样如果有一个子按钮没勾选上,那总按钮也不会勾选上。
接下来就是重难点了,如何实现点击所有子按钮后,总按钮自动勾选上?我的思路是遍历每个子按钮检测,如果有一个被勾选上,就+1,加到4就勾选总按钮。
这个比较难实现,我出了两次错误就放弃了。
第一次:设置了一个j变量接收累加值,但是每次进行遍历,j的值都会重置,这里错得离谱。
for (var i = 0; i < j_tbs.length; i++) {
j_tbs[i].onclick = function () {
for (var i = 0; i < j_tbs.length; i++) {
if (j_tbs[i].checked == false) {
j_cbAll.checked = false;
} else if (j_tbs[i].checked == true) {
// ⚠每次进入,j的值都会重置
var j = j;
j++
console.log(j);
if (j == 4) {
j_cbAll.checked = true;
}
}
}
}
}
第二次:在外部设置了一个num变量,用于遍历接收累加值。通过输出num的值发现问题。else if括号后的i值为##处的i值,即每次点击子按钮都会遍历检测一次,而不是检测点到的那个特定子按钮的选中情况,所以这种方法不可行
var num = 0;
for (var i = 0; i < j_tbs.length; i++) { // **
j_tbs[i].onclick = function () {
for (var i = 0; i < j_tbs.length; i++) { // ##
if (j_tbs[i].checked == false) {
j_cbAll.checked = false;
} else if (j_tbs[i].checked == true) {
num = num + 1;
console.log(num);
}
}
}
}
解决方法:
把不好实现的变成默认值就行了。
设置一个flag变量来决定总按钮的选中状态,每次点击子按钮,都会把flag重置为默认值true,把容易写的写好,剩下的交给flag判断。
细节:取反更简洁;break提高效率
完整代码如下:
<body>
<div>
<table class="goods">
<thead>
<tr>
<!-- 注意不要把class和id写混了 -->
<th><input type="checkbox" id="j_cbAll"></th>
<th>商品</th>
<th>价钱</th>
</tr>
</thead>
<tbody id="j_tb">
<tr>
<th><input type="checkbox"></th>
<td>苹果</td>
<td>100</td>
</tr>
<tr>
<th><input type="checkbox"></th>
<td>雪梨</td>
<td>100</td>
</tr>
<tr>
<th><input type="checkbox"></th>
<td>橘子</td>
<td>100</td>
</tr>
<tr>
<th><input type="checkbox"></th>
<td>香蕉</td>
<td>100</td>
</tr>
</tbody>
</table>
</div>
<script>
var j_cbAll = document.getElementById('j_cbAll');
var j_tbs = document.getElementById('j_tb').getElementsByTagName('input');
// (总)此事件实现全选
j_cbAll.onclick = function () {
// 点中全选键时实现遍历给下面的多选框赋true值(长度不是很理解,是tr有几个就有多长?)
for (var i = 0; i < j_tbs.length; i++) {
// 如果j_cbAll所在的按钮被点亮,则this.checked的值为true,那么赋给表身的checked值就是true,从而实现全选
j_tbs[i].checked = this.checked
}
}
// (总)此步骤实现下面全选后,上面全选的多选框可以勾上
// 第一个循环:遍历实现下面每个多选框被绑定
for (var i = 0; i < j_tbs.length; i++) {
j_tbs[i].onclick = function () {
// 第二个循环:检查下面每个多选框的选中情况
// 先定义一个flag变量用来控制全选框(默认为true,如果检查结果为没有未被选中的,则直接给j_cbAll.checked赋值为true这样全选框就被选中;如果有未被选中的,则先把flag值改为false,再赋值给它,这样全选框就没被选中)
var flag = true;
for (var i = 0; i < j_tbs.length; i++) {
// 某个按钮没有被选中,就把全选按钮改成false
if (!j_tbs[i].checked) {
// j_cbAll.checked == false;
flag = false;
// break可以提高执行效率
break;
}
}
j_cbAll.checked = flag;
}
}
</script>
</body>