iT邦幫忙

2021 iThome 鐵人賽

DAY 10
1
自我挑戰組

JS30 學習日記系列 第 10

Day 10 - Hold Shift to Check Multiple Checkboxes

  • 分享至 

  • xImage
  •  

前言

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 學習日記31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言