JS30 day10 Hold Shift to Check Multiple Checkboxes

Posted by Anthony Chao on 2019-11-10

JS30 day10 - Hold Shift to Check Multiple Checkboxes

作業內容

今天要做出按住 Shift 的時候可以達到同時選取好幾個 Checkbox 的效果,聽起來簡單,但邏輯上其實有點複雜(抱歉我太嫩)

可以參考這份 CodePen

學到什麼

  • JS

    1. 在 checkbox 身上加 click 的 event 時要記得不管是選擇或者取消都會觸發事件,如果只要選擇這個事件的話,記得要加上 this.checked 這個條件在後面的判斷式裡
    2. 上次有嚐到箭頭函式跟一般 function 裡面 this 的不同,所以這次有嘗試使用 var self = this 來解決
    3. 如果是在有按下 Shift 這個案件的情況下的事件,那麼這個事件本身的 shiftKey 屬性是 true,因此判斷式只要寫 if(e.shiftKey... 就可以了
    4. 這裡面邏輯比較難懂的是中間這段,為了方便理解加了 console.log 來輔助
      如果其中一個 checkbox 被點選(條件一),而且是被選擇不是取消(條件二),再加上有按著 Shift 的話(條件三),Checkboxes 會開始跑回圈,先報出自己是誰,如果你是剛剛被點的這個 checkbox 或者你是 lastChecked 的話再喊聲 start
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    if(e.shiftKey && this.checked){
    checkboxes.forEach(function(checkbox){
    console.log(self)
    if(checkbox === self || checkbox === lastChecked){
    inBetween = !inBetween
    console.log("start!")
    }

    if(inBetween){
    checkbox.checked = true;
    }
    })
    }

參考資料:
https://github.com/wesbos/JavaScript30

code 內容:
HTML:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<div class="inbox">
<div class="item">
<input type="checkbox">
<p>This is an inbox layout.</p>
</div>
<div class="item">
<input type="checkbox">
<p>Check one item</p>
</div>
<div class="item">
<input type="checkbox">
<p>Hold down your Shift key</p>
</div>
<div class="item">
<input type="checkbox">
<p>Check a lower item</p>
</div>
<div class="item">
<input type="checkbox">
<p>Everything in between should also be set to checked</p>
</div>
<div class="item">
<input type="checkbox">
<p>Try to do it without any libraries</p>
</div>
<div class="item">
<input type="checkbox">
<p>Just regular JavaScript</p>
</div>
<div class="item">
<input type="checkbox">
<p>Good Luck!</p>
</div>
<div class="item">
<input type="checkbox">
<p>Don't forget to tweet your result!</p>
</div>
</div>

CSS:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
html {
font-family: sans-serif;
background: #ffc600;
}

.inbox {
max-width: 400px;
margin: 50px auto;
background: white;
border-radius: 5px;
box-shadow: 10px 10px 0 rgba(0,0,0,0.1);
}

.item {
display: flex;
align-items: center;
border-bottom: 1px solid #F1F1F1;
}

.item:last-child {
border-bottom: 0;
}

input:checked + p {
background: #F9F9F9;
text-decoration: line-through;
}

input[type="checkbox"] {
margin: 20px;
}

p {
margin: 0;
padding: 20px;
transition: background 0.2s;
flex: 1;
font-family:'helvetica neue';
font-size: 20px;
font-weight: 200;
border-left: 1px solid #D1E2FF;
}

JS:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
const  checkboxes= document.querySelectorAll('.inbox input[type="checkbox"]')
let lastChecked
function handleCheck(e){
// self 是被點的 checkbox
let self = this
let inBetween = false;
if(e.shiftKey && this.checked){
checkboxes.forEach(function(checkbox){
if(checkbox === self || checkbox === lastChecked){
inBetween = !inBetween
}

if(inBetween){
checkbox.checked = true;
}
})
}
lastChecked = this;
}

checkboxes.forEach(function(checkbox){
checkbox.addEventListener('click', handleCheck)
})




prevent_hack