[Javascript 30] Day 10 - 쉬프트 키 누른데까지 다 체크하기

이사감·2021년 2월 5일
0

Javascript 30

목록 보기
10/15
post-thumbnail

Day 10 - Hold Shift and Check Checkboxes

요구사항

  • 마지막으로 체크한 것과, 이후 쉬프트 키를 누른채 체크한 것 사이의 체크박스들이 자동으로 체크되기
  • 해당 기능은 상하 방향 순서 상관없이 발생하기

TIL

오늘은 새로 알게된 내용은 거의 없고, 그 무엇보다도 코드를 이해하는 것에 중점을 둔 학습이었다고 해야하나..
특히 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 변수

두 체크 사이의 것들을 자동으로 체크되게 만들 것이지만, 변수로 기록하는 것은 하나입니다.
쉬프트 키를 누른 채로 체크하기 전에, 쉬프트 키를 안 누르고 체크한 마지막 것.
이 마지막 체크는 lastChecked라는 변수로 따로 기록됩니다.
이것은 별도의 코드를 작성하지 않더라도 상하 / 하상 두 방향 모두 커버하게 만드는 역할을 합니다.
if(checkbox === this || checkbox === lastChecked)
에 의해 언제든지 아래의 것이 시작점이 될 수도 있고, 위의 것이 시작점이 될 수도 있기 때문입니다.

input 체크박스 in JS

HTML의 input 체크박스들은 querySelectorAll에 의해 배열로 자바스크립트에 불러와졌습니다.
따라서 forEach문으로 각 체크박스에 클릭 이벤트가 발생했을 때 handleCheck 함수가 실행되도록 작성되었습니다.

event.shiftKey

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;
}

이제 이 로직은 실행되지 않습니다.

이런 과정에 따라, 쉬프트 키를 누르고 체크박스를 클릭한 곳 까지 체크박스들이 모두 체크된 상태로 자동으로 변함!

profile
https://emewjin.github.io

0개의 댓글