Day 10 - JS Checkbox Challenge!

이번 과제는 Shift 키 이벤트로 Checkbox 객체를 다중 선택할 수 있게 한다. 예를 들어, Gmail, 윈도우의 개체를 선택하고 Shift키와 함께 선택한 요소에서부터 다음에 선택한 요소까지 다중으로 선택되는 기능을 구현하는 것이다.

css + 속성

우선 css부터 이해가 필요하다. 체크박스 객체가 선택되었을 때 옆에 딸린 p 객체를 어떻게 줄을 그을 것인지, 물론 Javascript로도 할 수 있지만 css의 기본 속성으로도 구현할 수 있다.

1
2
3
4
input:checked + p {
background: #f9f9f9;
text-decoration: line-through;
}

간단하다. input 객체가 checked 상태일 때 +를 통해서 p의 css 속성을 제어할 수 있다. checked 말고도 hover, focus 등의 여러가지 속성이 많다.

Script Part

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

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

let lastChecked;

function handleCheck(e) {
let inBetween = false;
if (e.shiftKey && this.checked) {
checkboxes.forEach(checkbox => {
console.log(checkbox);
if (checkbox === this || checkbox === lastChecked) {
inBetween = !inBetween;
console.log('Starting to check them in between!');
}
if (inBetween) {
checkbox.checked = true;
}
});
}
lastChecked = this;
}

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

우선 체크박스 객체 전체를 선언하고 마지막에 체크된 객체를 저장하기 위해 lastChecked를 따로 만든다.

이제 체크박스들에 handleCheck() 함수를 이벤트로 걸어주는데, inBetween을 그냥 보면 이해가 어려울 것이다.

완성된 예제를 잘 생각해보자. 마지막에 선택한 체크박스 객체와 지금 클릭한 체크박스 객체 사이를 checked로 만들어주면 된다. 여기서 중간의 체크박스 객체들을 inBetween = true로 구분하여 체크해주는 것이다. 처음에는 inBetweenfalse로 초기화시킨 후, 마지막에 선택했거나, 지금 클릭했다면 그 때 inBetweentrue로 업데이트되고, 또 다시 마지막에 선택했거나, 지금 클릭했다면 false로 업데이트되면서 중간의 객체들이 모두 체크된다. 이 방법을 이용하면 밑에서 위로 체크하는지, 위에서 밑으로 체크하는지 별도로 구현할 필요가 없다.

아마 이번 과제를 배우지 않았다면 bottomUp, upBottom을 선언하여 따로 구분짓고 for loop를 돌렸을 것 같다. 기발한 아이디어는 가독성, 효율 모두 좋게 만든다. 더 노력해야겠다.