[wesbos30] 10. Hold Shift to check the box
약 3분 소요
![[wesbos30] 10. Hold Shift to check the box](https://firebasestorage.googleapis.com/v0/b/cruz-lab.firebasestorage.app/o/images%2Fheroes%2Fhero-1764848953198.webp?alt=media&token=dba9218a-ddeb-4f23-8ce7-07b30d99ca9e)
💡 SHIFT 키와 같이 클릭하여 한번에 여러 개의 체크박스를 모두 체크하는 기능을 구현해보자!
로직
- 임의의 체크박스를 클릭하여 체크한 후 그 박스를 기억한다.
- SHIFT 키와 같이 클릭한 것 인식하게 하기
- 체크박스를 SHIFT 키와 같이 클릭할 경우 그 체크박스와 기억해둔 가장 최근의 체크박스 사이의 모든 체크박스 체크하기
코딩 과정
1. 최근 체크 박스 기억하기
const checkboxes = document.querySelectorAll('.inbox input[type="checkbox"]')
let lastChecked
function handleCheck(e) {
lastChecked = this
}
checkboxes.forEach(checkbox => checkbox.addEventListener('click', handleCheck))
핸들러를 생성하기에 앞서 미리 lastChecked 변수를 선언해주고
체크박스를 클릭할 때마다 lastChecked 값을 해당 체크박스로 업데이트 시켜준다.
2. SHIFT 키 인식하기
const checkboxes = document.querySelectorAll('.inbox input[type="checkbox"]')
let lastChecked
function handleCheck(e) {
if (e.shiftKey && this.checked) {
console.log('쉬프트 키 눌림!')
}
lastChecked = this
}
checkboxes.forEach(checkbox => checkbox.addEventListener('click', handleCheck))
event.shiftKey
마우스이벤트, 키보드이벤트 발생 시 SHIFT 키가 눌렸는지 여부를 Boolean 값으로 반환해준다.
SHIFT 키와 마찬가지로 event.altKey, event.ctrlKey 또한 존재한다.
3. 두 체크박스 사이의 체크박스들 동시 체크
const checkboxes = document.querySelectorAll('.inbox input[type="checkbox"]')
let lastChecked
function handleCheck(e) {
let inBetween = false
if (e.shiftKey && this.checked) {
checkboxes.forEach(checkbox => {
if (checkbox === this || checkbox === lastChecked) {
inBetween = !inBetween
}
if (inBetween) {
checkbox.checked = true
}
})
}
lastChecked = this
}
checkboxes.forEach(checkbox => checkbox.addEventListener('click', handleCheck))
먼저 각 체크박스들이 사이에 있는 체크박스인지에 대한 여부를 Boolean 값으로 판단하기 위해 inBetween 변수를 선언해 준다.
그 후 만약 SHIFT 키와 같이 클릭이 되면 forEach 메서드로 모든 체크박스에 대하여 다음 두 가지를 검사한다.
- 만약 체크박스가
this(이벤트가 발생한 체크박스)거나lastChecked(최근에 누른 체크박스)이면inBetween값을 반대로 설정 - 만약
inBetween값이true면 체크박스를 체크 후 다음 체크박스 검사
위 코드에 의해 다음과 같은 과정으로 이벤트가 발생한다.
- 임의의 체크박스 클릭 ⇒
lastChecked업데이트 &inBetween값으로false할당 - 또 다른 체크박스를 SHIFT 키와 함께 클릭
⇒forEach메서드로 모든 체크박스 검사 시작
⇒this거나lastChecked인 체크박스가 나오기 전까진inBetween값이false이므로 아무 변경 사항 없이 다음 차례로 넘어감
⇒this거나lastChecked인 체크박스가 나오면inBetween값이true로 바뀜
⇒ 다음 차례부턴inBetween값이true이므로 체크박스를 체크 후 다음 차례로 넘어감
⇒this나lastChecked중 나머지 체크박스가 나오면inBetween값이 다시false로 바뀌면서 이후 차례의 체크박스들은 다시 아무 변경 사항 X
최종 완성 코드
const checkboxes = document.querySelectorAll('.inbox input[type="checkbox"]')
let lastChecked
function handleCheck(e) {
let inBetween = false
if (e.shiftKey && this.checked) {
checkboxes.forEach(checkbox => {
if (checkbox === this || checkbox === lastChecked) inBetween = !inBetween
if (inBetween) checkbox.checked = true
})
}
lastChecked = this
}
checkboxes.forEach(checkbox => checkbox.addEventListener('click', handleCheck))