美文网首页
10 Hold Shift and Check Checkbox

10 Hold Shift and Check Checkbox

作者: 地平线0530 | 来源:发表于2018-12-17 17:05 被阅读0次

效果

效果图

Demo
Github

知识点

  • input[type="checkbox"]
    • checked
  • Event
    • shiftKey

笔记

本例需要实现通过按住 shift 键,可以批量选中复选框。

本例的难点是如何判断两个被选中 input 元素之间的范围,只要解决了这个,本例就不难了。

Wes Bos 的思路是通过声明一个变量,这个变量只有两个值:truefalse,初始值设为 false,我们把它当做一个开关,如果当这个开关处于 true 状态时, input 元素都应该为 checked(选中)状态。

我们先获取所有的 input 元素:

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

let lastChecked

同时声明一个变量 lastChecked 用来记录最后点击的那个 input 元素。

此时可以给所有 input 元素添加事件监听,我们同时创建一个函数 handleCheck 用来处理这些事件:

function handleCheck(e) {
  let inBetween = false
  lastChecked = this
}

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

这里的变量 inBetween 就是我们前面提到的那个开关。

此时,完善函数,使其判断只有在 shift 键按下且 input 处于选中状态时,才开启开关 inBetween:

function handleCheck(e) {
  let inBetween = false

  if (e.shiftKey && this.checked) {
    inBetween = true
  }

  lastChecked = this
}

此时我们可以通过 forEach 遍历,来改变其他 input 元素的状态:

function handleCheck(e) {
  let inBetween = false

  if (e.shiftKey && this.checked) {
    checkboxes.forEach(checkbox => {
      inBetween = true

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

  lastChecked = this
}

现在,我们运行一下,看看效果……

你会发现,我们并没有实现要求,不该选的 input 也全都选中了,这是为什么呢?

forEach() 方法遍历,会从头到尾把所有能遍历的元素都遍历一遍,这样一来,其实从头到尾,inBetween 这个开关一直是开着的,我们需要增加一个判断,使其在不需要时关闭,需要时打开。我们继续改写函数:

function handleCheck(e) {
  let inBetween = false

  if (e.shiftKey && this.checked) {
    checkboxes.forEach(checkbox => {
      // inBetween = true 删除这一句!

      if (checkbox === this || checkbox === lastChecked) {
        inBetween = !inBetween
      }

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

  lastChecked = this
}

如上:我们判断只有当循环遇到 lastChecked 或者当前点击的那个 input 时,inBetween 状态进行反转。这时我们在运行程序看看,OK,大功告成!

相关文章

网友评论

      本文标题:10 Hold Shift and Check Checkbox

      本文链接:https://www.haomeiwen.com/subject/owyckqtx.html