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 10] 练练CSS,加强实作练习

>>:  Day 6 - 唯一与职缺有关的工作内容

Progressive Web App Manifest: 配置档属性深入介绍 (5)

Web App 的 manifest 是一个 JSON 形式的配置档,浏览器透过配置档就会知道 Pr...

802.1X 是网路访问控制 (NAC) 的 IEEE 标准

-802.1X 角色 .请求者不直接向 RADIUS 服务器进行身份验证。它向身份验证者进行身份验...

#Day1--开始之前

在铁人赛的第一天,我大概会谈几个我曾经问过我自己的问题,或许可以给一些正在思考着要不要写程序的一些人...

Day 16 : 特徵工程 tf.Tramsform 实作

接续 Day 15 的 tf.Tramsform 介绍,今日进行实作,先以TensorFlow Tr...

用 Python 畅玩 Line bot - 08:Audio message part2

既然可以将音档转为文字回传了,接下来我们可以尝试看看将收到的 Text message 转为音档去进...