iT邦幫忙

2021 iThome 鐵人賽

DAY 10
0
自我挑戰組

JS30 學習日記系列 第 10

Day 10 - Hold Shift to Check Multiple Checkboxes

前言

JS 30 是由加拿大的全端工程師 Wes Bos 免費提供的 JavaScript 簡單應用課程,課程主打 No FrameworksNo CompilersNo LibrariesNo Boilerplate 在30天的30部教學影片裡,建立30個JavaScript的有趣小東西。

另外,Wes Bos 也很無私地在 Github 上公開了所有 JS 30 課程的程式碼,有興趣的話可以去 fork 或下載。


本日目標

在已經勾選一個核取方塊的前提下,按住shift鍵並勾選第二個方塊,最後將第一、二個方塊之間的方塊都勾選起來,實現同時勾選複數方塊的目的。


解析程式碼

HTML 部分

由最外層的 div(.inbox) 包覆住內部多個 div(.item),每個div(.item) 都是以一個核取方塊(checkbox)搭配說明文字(p)組合而成。

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

JS 部分

首先,宣告一個常數 checkboxes 並取得所有網頁上的核取方塊(checkbox)。

接著,宣告一個變數 lastChecked 用來幫我們記住上一次勾選的核取方塊(checkbox)。

const checkboxes = document.querySelectorAll('.inbox input[type="checkbox"]');
let lastChecked;

我們在每個 checkbox 上都註冊 click 事件監聽器,當事件觸發就以handleCheck()進行事件處理。

handleCheck()裡面,我們可以用lastChecked = this;來記住上一次選取的方塊。

function handleCheck(e){
    lastChecked = this;//更新上次勾選的點
}

checkboxes.forEach(checkbox => checkbox.addEventListener('click',handleCheck));

我們進行多選核取方塊的邏輯是先勾選其中一個作為起始點,之後按住shift鍵勾選終點方塊,而在起、終點之間的方塊都會被勾選。

handleCheck()裡,可以使用 if 判斷現在是不是有按下shift鍵並同時勾選方塊,之後再做勾選間隔方塊的處理。

function handleCheck(e){
    //檢查是否有按下shift鍵並選取方塊
    if(e.shiftKey && this.checked){
      
    }

    lastChecked = this;//更新上次勾選的點 
}

宣告一個變數inBetween判斷checkbox是否處在起、終點的checkbox之間。

checkboxes上呼叫forEach()對其下的每一個checkbox進行判斷。當這個checkbox是剛剛按住shift鍵勾選的checkbox,此時將inBetween設為 true;當這個checkboxlastChecked,此時改將inBetween設為 false。

最後一個 if 判斷用來幫我們將起、終點之間的方塊通通勾選起來。

function handleCheck(e){
    let inBetween = false;//用來判斷checkbox是否被夾在起、終點之間
    
    //檢查是否有按下shift鍵並選取方塊
    if(e.shiftKey && this.checked){
      checkboxes.forEach(checkbox => {
        //將起始點的inBetween設為true、結束點的inBetewwn設為false作為斷點
        if(checkbox === this || checkbox === lastChecked){
          inBetween = !inBetween;
        }

        if(inBetween){//打勾夾在起點和終點的checkbox
          checkbox.checked = true;
        }
      })
    }

    lastChecked = this;//更新上次勾選的點
}
舉例說明:

假設現在先勾選第一個方塊,之後按住shift鍵並勾選第八個方塊,此時第一個方塊就會是lastChecked,而第八個方塊則是this剛剛勾選的。

checkboxes上呼叫forEach()對其下的每一個checkbox進行判斷時,遇到第一個方塊也就是lastChecked就將inBetween改成 true,遇到第八個方塊也就是this則將inBetween改成 false。

最後,第一個方塊到第七個方塊的inBetween都會是 true,第八個方塊則是 false。作 if 判斷時,我們將inBetween是 true 的勾選起來,勾到第八個剛好inBetween是 false 成為一個勾選的終止點,成功地一次勾選八個方塊。

補充資料:

KeyboardEvent.shiftKey

範例網頁請點此


上一篇
Day 9 - 14 Must Know Dev Tools Tricks
下一篇
Day 11 - Custom HTML5 Video Player
系列文
JS30 學習日記30

尚未有邦友留言

立即登入留言