这是我参与更文挑战的第12天,活动详情查看: 更文挑战
Hold Shift to Check Multiple Checkboxes
这个模块的主要实现的是通过操控键盘按键去实现按下 shift 按键之后实现 checkbox 的多选操作的功能。在初始文档中提供了一组类型为 checkbox 的 input 标签,选中某个checkbox 时,其文字会显示删除线效果。我们根据原作者提供的初始化文档,完成之后的实现效果。
一、效果展示
1.index-START.html
2.index-FINISHED.html
3. 我的效果
二、实现
最终代码
<script>
;(function(){
const checkboxes = Array.from(document.querySelectorAll('.inbox input[type="checkbox"]'));
let lastCheck = null;
function clickHandler(e){
console.log(e);
if(this.checked){
if(e.shiftKey && lastCheck !== null){
let nowCheck = checkboxes.indexOf(this);
checkboxes.slice(
Math.min(nowCheck.lastCheck),
Math.max(nowCheck,lastCheck)
)
.forEach(input => (input.checked = true));
}
lastCheck = checkboxes.indexOf(this); //如果是打钩状态,记录下来
} else {
lastCheck = null; //否则清掉
}
}
checkboxes.forEach(input =>{
input.addEventListener("click",clickHandler);
})
})()
</script>
三、总结回顾
拿到模块的题目,我们首要做一个思考,这部分模块我感觉非常的有意思。
当在键盘上按下 Shift 键进要实现多选操作的时候,我们整个过程应该是怎么样的?我们来还原一下整个过程,顺便剖析一下原作者的解决思路。
-
选中某一项(记为 a);
-
按下 shift 按键;
-
在选中一项(记为 b);
-
a 和 b 之间的部分都被选中。
整个的过程应该就是这样的了,这是按照描述的操作过程,那么这样我就产生了一些疑问。
-
如果我一开始就按下了 shift 按键呢?
-
如果我选中了某一项,然后我再取消,然后紧接着按下 shift 按键又会是怎么样的呢?
-
如果我选中了某一项,并且按下了 shift 按键选中了另外一项,这时候我将 a 和 b 之间的某一项取消选中之后,然后我再次按下 shift 按键之后,选中另外一项(记为 c),这时候包含在 a 和 b 之间的选中部分会被取消选中吗?
然后带着这些疑问我就去操作了原作的最终实现效果,然后我发现:
当我刚进入页面没有进行选中某一项,而是直接执行按下 shift 按键的操作的时候,这个时候内容是全部选中的。
你看,真是普通且自信。
然后我思考了一下,发现其实一开始我的想法就是——
如果要实现按下 shift 按键的时候,选中 a 和 b 之间的部分,那么就用一个变量,来标记这个范围。将变量初始值为 false,当按下 Shift 键并且同时选中了某个元素的时候,遍历这个范围的所有项,如果遇到 a 或 b,则将标记值取反。同时,将所有标记为 true 的项设置为选中。这时候就实现了我们想要的结果。
但是如果这样去操作呢,就会出现一个问题,当进入页面直接选择按住 Shift 再点击某一项,那么这一项之后的元素都会被选中——完求了,一下子思路跨国接轨了,然后还都是有 bug 的。并且,对于取消选中,无法批量操作。
那么,我们就选择用另一种方式(slice)尝试一下吧。
过程分解
1.选中所有 checkbox 元素进行操作。 首先找到所有的类型为 checkbox 的 input 元素,然后进行 Array.from 将其变成一个阵列(为什么这样变化,因为我要用 slice 啊,好整啊...)。
const checkboxes = Array.from(document.querySelectorAll('.inbox input[type="checkbox"]'));
那么 Arrary.from 如何使用呢?
MDN不请自来!
链接地址:developer.mozilla.org/zh-CN/docs/…
操作之后就变成了这样的形式啦。
- 事件监听。
function clickHandler(e){
console.log(e);
}
checkboxes.forEach(input =>{
input.addEventListener("click",clickHandler);
})
这里可以先看一下 clickHandler 方法里的 e 都有哪些属性.
这样我们就知道我们要操作的就是 shiftKey ,当按住 shift 按键选中某一项的时候,此时 shiftKey 的状态变成了 true。
- 区间 a 的判断。
let lastCheck = null;
function clickHandler(e){
console.log(e);
if(this.checked){
lastCheck = checkboxes.indexOf(this); //如果是打钩状态,记录下来
} else {
lastCheck = null; //否则清掉
}
}
checkboxes.forEach(input =>{
input.addEventListener("click",clickHandler);
})
- 效果实现:
·let lastCheck = null;
function clickHandler(e){
console.log(e);
if(this.checked){
if(e.shiftKey && lastCheck !== null){
let nowCheck = checkboxes.indexOf(this);
checkboxes.slice(
Math.min(nowCheck.lastCheck),
Math.max(nowCheck,lastCheck)
)
.forEach(input => (input.checked = true));
}
lastCheck = checkboxes.indexOf(this); //如果是打钩状态,记录下来
} else {
lastCheck = null; //否则清掉
}
}
checkboxes.forEach(input =>{
input.addEventListener("click",clickHandler);
})
这样就已经实现了我们的这个功能:
四、重难点
大概率已经分析到了上边的总结中去做了思考,虽然它出错了片场,但是还是要完美的进行演绎,毕竟——成年人,都不容易!
记得按时学习!