Anthony Chao

JS30 day10 Hold Shift to Check Multiple Checkboxes

#Javascript

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
    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:

<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:

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:

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)
})