오늘은 새로 알게된 내용은 거의 없고, 그 무엇보다도 코드를 이해하는 것에 중점을 둔 학습이었다고 해야하나..
특히 handleCheck 함수가 어떻게 굴러가는지를 이해하기가 어려워 시간이 좀 걸렸고
대신 그 과정에서 저저번 시간에 정리했던 boolean 값을 통한 flag(플래그) 활용을 응용 & 이해할 수 있었음.
이 플래그 활용이 계산기 만들 때도 그렇고, 조건문에서 많이 쓰이는 것 같은데 여전히 헷갈리고 어렵다...
차근차근 보겠습니다. 글로 설명 쓰려니까 더 어려운거 같다
handleCheck 코드
function handleCheck(e){ let inBetween = false; if(e.shiftKey && this.checked){ checkboxes.forEach(checkbox => { console.log(checkbox); if(checkbox === this || checkbox === lastChecked) { inBetween = !inBetween; } if(inBetween){ checkbox.checked=true; } }); } lastChecked = this; }
두 체크 사이의 것들을 자동으로 체크되게 만들 것이지만, 변수로 기록하는 것은 하나입니다.
쉬프트 키를 누른 채로 체크하기 전에, 쉬프트 키를 안 누르고 체크한 마지막 것.
이 마지막 체크는 lastChecked라는 변수로 따로 기록됩니다.
이것은 별도의 코드를 작성하지 않더라도 상하 / 하상 두 방향 모두 커버하게 만드는 역할을 합니다.
if(checkbox === this || checkbox === lastChecked)
에 의해 언제든지 아래의 것이 시작점이 될 수도 있고, 위의 것이 시작점이 될 수도 있기 때문입니다.
HTML의 input 체크박스들은 querySelectorAll에 의해 배열로 자바스크립트에 불러와졌습니다.
따라서 forEach문으로 각 체크박스에 클릭 이벤트가 발생했을 때 handleCheck
함수가 실행되도록 작성되었습니다.
event.shiftKey
는 쉬프트 키가 눌렸을 경우 true, 아닌 경우 false를 반환합니다.
handleCheck
로직 이해이제 상황을 가정하여 handleCheck
를 들여다보겠습니다.
여기 5개의 체크박스가 있다고 합시다.
1
2
3
4
5
우리가 1번 체크박스를 클릭하면 (헷갈리니까 체크한 것을 클릭한 것이라고 말하겠습니다.) handleCheck
함수에 의해 inBetween이라는 플래그가 세워집니다. 값은 false인 상태입니다. 이제부터 플래그의 상태에 주목해야 합니다.
function handleCheck(e){
let inBetween = false;
1번 체크박스를 클릭한 것은 lastChecked에 기록됩니다.
lastChecked = this;
그리고 5번 체크박스를 Shift키를 누른채 클릭했습니다.
원하는 것은 5번을 쉬프트와 함께 클릭했을 때, 2,3,4번이 자동으로 체크되는 것입니다.
5번은 쉬프트를 누른채로 클릭했으므로
if(e.shiftKey && this.checked)
이 조건을 만족하여 if문의 forEach
문이 실행됩니다.
if(e.shiftKey && this.checked){
checkboxes.forEach(checkbox => {
console.log(checkbox);
if(checkbox === this || checkbox === lastChecked) {
inBetween = !inBetween;
console.log(inBetween);
console.log('Starting to check them in between!');
}
if(inBetween){
checkbox.checked=true;
}
});
}
이 forEach
문은 배열 각 요소, 즉 체크박스들에 대해 오름차순으로 (1-2-3-4-5) 화살표 함수를 실행합니다.
forEach()는 주어진 callback을 배열에 있는 각 요소에 대해 오름차순으로 한 번씩 실행합니다. 삭제했거나 초기화하지 않은 인덱스 속성에 대해서는 실행하지 않습니다.
MDN
forEach
문이 1번 체크박스를 보았더니,
if(checkbox === this || checkbox === lastChecked)
이 조건을 만족합니다. 따라서 inBetween = !inBetween;
가 실행되어 플래그는 false에서 true로 반전됩니다.
forEach
문이 수행하는 것 중에는 만일 플래그가 true일 경우, 체크박스를 체크된 상태로 만드는 if문이 있습니다.
if(inBetween){
checkbox.checked=true;
}
이에 따라 플래그가 false가 될 때까지, 각 체크박스들은 forEach
문의 루프에 의해 체크된 상태로 변합니다.
1번 체크박스에 대한 판단을 마친 forEach
문이 2번, 3번, 4번 체크박스를 보았더니
if(checkbox === this || checkbox === lastChecked)
이 조건을 만족하지 않습니다. 따라서 flag 반전도 일어나지 않고, 여전히 true인 상태라 2,3,4번 체크박스는 클릭이 됩니다.
마지막으로 forEach
문이 5번 체크박스를 보았더니,
if(checkbox === this || checkbox === lastChecked)
이 조건을 만족하고 있습니다. 따라서 플래그 반전이 일어나 true에서 false로 변경되고, 플래그는 더이상 true가 아니므로
if(inBetween){
checkbox.checked=true;
}
이제 이 로직은 실행되지 않습니다.
이런 과정에 따라, 쉬프트 키를 누르고 체크박스를 클릭한 곳 까지 체크박스들이 모두 체크된 상태로 자동으로 변함!