排他思想在进行页面交互时经常用到,所谓排他思想,顾名思义就是其他元素无此样式效果或事件,只有当前操作的元素拥有。
如果有同一组元素,我们想要某一个元素实现某种样式, 需要用到循环的排他思想算法:
1. 所有元素全部清除样式(干掉其他人)
2. 给当前元素设置样式 (留下我自己)
3. 注意顺序不能颠倒,首先干掉其他人,再设置自己
接下来,以几个案例来更直观的介绍下该思想的核心点:
1.案例:表格隔行变色
<!-- css样式 --> <style> table { margin: 50px; width: 700px; text-align: center; border-collapse: collapse; } thead tr { background-color: #D4EEFF; } th, td { height: 40px; border-top: 1px solid #666; border-bottom: 1px solid #666; } </style> <body> <!-- html结构 --> <table> <thead> <tr> <th>代码</th> <th>名称</th> <th>最新公布净值</th> <th>累计净值</th> <th>前单位净值</th> <th>净值增长率</th> </tr> </thead> <tbody> <tr> <td>020313</td> <td>农银金穗3个月定期</td> <td>1.075</td> <td>1.293</td> <td>1.023</td> <td>+0.342%</td> </tr> <tr> <td>013237</td> <td>广发理财30天债券B</td> <td>0.893</td> <td>3.293</td> <td>0.023</td> <td>+0.000%</td> </tr> <tr> <td>193725</td> <td>兴全合宜混合A</td> <td>0.862</td> <td>0.862</td> <td>0.863</td> <td>-0.362%</td> </tr> <tr> <td>002842</td> <td>中银证券安进债券A</td> <td>1.075</td> <td>1.293</td> <td>1.924</td> <td>+0.092%</td> </tr> <tr> <td>304284</td> <td>光大添天盈月度理财债券</td> <td>0.902</td> <td>3.492</td> <td>0.00</td> <td>+0.000%</td> </tr> </tbody> </table> <!-- js代码 --> <script> // 1. 获取元素 let trs = document.querySelectorAll("tbody tr"); // 2. 循环注册事件 for (let i = 0; i < trs.length; i++) { // 3. 鼠标经过事件 onmouseover trs[i].onmouseover = function() { this.style.backgroundColor = '#ccc'; } // 4. 鼠标离开事件 onmouseout trs[i].onmouseout = function() { this.style.backgroundColor = ''; } } </script> </body>
案例分析:
① 用到鼠标事件 鼠标经过 onmouseover 鼠标离开 onmouseout
② 核心思路:鼠标经过 tr 行,当前的行变背景颜色, 鼠标离开去掉当前的背景颜色
③ 注意: 第一行(thead里面的行)不需要变换颜色,因此我们获取的是 tbody 里面的行
2.案例:表单全选取消全选功能
需求:
1. 点击上面全选复选框,下面所有的复选框都选中(全选)
2. 再次点击全选复选框,下面所有的复选框都不中选(取消全选)
3. 如果下面复选框全部选中,上面全选按钮就自动选中
4. 如果下面复选框有一个没有选中,上面全选按钮就不选中
5. 所有复选框一开始默认都没选中状态
<!-- css样式 --> <style> table { margin: 50px; width: 500px; text-align: center; border-collapse: collapse; } thead tr { background-color: #D4EEFF; } th, td { height: 40px; border-top: 1px solid #666; border-bottom: 1px solid #666; } </style> <body> <!-- html结构 --> <table> <thead> <tr> <th> <input type="checkbox" id="checkAll"> </th> <th>商品</th> <th>价格</th> </tr> </thead> <tbody> <tr> <td> <input type="checkbox"> </td> <td>华为手机</td> <td>¥5500.00</td> </tr> <tr> <td> <input type="checkbox"> </td> <td>小米手机</td> <td>¥3800.00</td> </tr> <tr> <td> <input type="checkbox"> </td> <td>苹果手机</td> <td>¥6199.00</td> </tr> <tr> <td> <input type="checkbox"> </td> <td>vivo手机</td> <td>¥3199.00</td> </tr> </tbody> </table> <!-- js代码 --> <script> // 1. 获取元素 let checkAll = document.getElementById('checkAll'); let checks = document.querySelectorAll("tbody input"); // 2. 给全选按钮绑定事件 checkAll.onclick = function() { // 获取当前按钮的选中状态值,遍历checks,让tbody中的复选框的选中状态与其保持一致,就实现了全选按钮的功能 checks.forEach(item => item.checked = this.checked); }; // 3. 通过遍历给tbody中的每个复选框绑定事件 for (let i = 0; i < checks.length; i++) { checks[i].onclick = function() { // 如果当前按钮未选中,则全选按钮保持未选中状态 if (this.checked == false) { checkAll.checked = false; // 如果当前按钮选中,再去判断其他按钮是否选中 } else { // 如果tbody中不被选中的input为空,说明全部被选中,则此时全选按钮也为选中状态 if (document.querySelector('tbody input:not(:checked)') == null) { checkAll.checked = true; } } } }; </script> </body>
案例分析:
① 全选和取消全选做法: 让下面所有复选框的checked属性(选中状态) 跟随全选按钮即可
② 下面复选框需要全部选中, 上面全选才能选中做法: 通过循环遍历给下面所有复选框都绑定点击事件,每次点击,都先去判断当前复选框是否选中,如果未选中,则全选按钮自然就是不选中状态,如果是选中的,再去判断是否所有的复选框都选中,如果都选中则将全选按钮的状态改为true。
实现tbody中复选框的功能需求的第二种方法如下,但是,注意和上面方法重复的代码就不再赘述,仅把JS中第3点的不同之处写在了下面:
// 3. 通过遍历给tbody中的每个复选框绑定事件 for (let i = 0; i < checks.length; i++) { checks[i].onclick = function() { // 定义一个变量flag,来控制全选按钮的状态,默认为true let flag = true; // 每点击tbody中的一个复选框,都要去循环检查每个复选框是否全被选中 for (let i = 0; i < checks.length; i++) { if (!checks[i].checked) { // 如果有未选中的复选框,则将flag改为false flag = false; // 同时使用break退出循环,因为一旦有一个未选中,那么全选按钮就不选中,这样可以提供执行效率 break; }; }; // 最后将flag的值赋值给全选按钮的checked属性 checkAll.checked = flag; } };
方法分析:
① 下面复选框需要全部选中, 上面全选才能选中做法: 给下面所有复选框绑定点击事件,每次点击,都要循环查看下面所有的复选框是否有没选中的,如果有一个没选中的, 上面全选就不选中。
② 可以设置一个变量,来控制全选是否选中。