본문 바로가기
DEV/JS30

[JS30] day 10 - Hold shift to check multiple checkboxes

by newjp 2021. 12. 28.

처음과 쉬프트+끝을 선택하면 중간 요소들이 모두 선택되는 체크 리스트를 만들자

The following is a common layout you would see in an email client. When a user clicks a checkbox, holds Shift, and then clicks another checkbox a few rows down, all the checkboxes inbetween those two checkboxes should be checked.

 

HTML / CSS

<div class="inbox">
    <div class="item">
      <input type="checkbox">
      <p>This is an inbox layout.</p>
    </div>
    <div class="item">
      <input type="checkbox">
      <p>Check one item</p>
    </div>
    <div class="item">
      <input type="checkbox">
      <p>Hold down your Shift key</p>
    </div>
		...
		(생략)
		...
</div>
input:checked + p {
      background: #F9F9F9;
      text-decoration: line-through;
    }

.inbox 전체를 감싸는 div 안에 체크 리스트를 감싸는 .item div, 그 안에는 checkbox와 글이 들어있음

  • 인접 형제 선택자 + 형제 관계란 같은 부모를 가지는 것, A + B의 형식으로 쓰며 A와 B사이에 다른 형제가 있다면 선택하지 않음 현재 사용 용도는 체크 리스트가 체크 되면 p가 선택되어 p에 스타일을 줌, line-through와 배경색을 어둡게 하여 체크 된 느낌을 줌

JS

<script>

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 inbetween')
      }

      if (inBetween) {
        checkbox.checked = true;
      }
    });
  }
  lastChecked = this;
}
checkboxes.forEach(checkbox => checkbox.addEventListener('click', handleCheck));

</script>

checkboxes 안의 check 를 클릭하면 Eventlistner 시작하고 handleCheck 함수를 시작

그냥 클릭 ⇒ lastChecked는 지금 클릭한 check로 업데이트 해 준다

shift키 + 클릭 ⇒ 더 클릭 처리 할 것이 있나 if문 안으로 찾으러 감

찾는 방법은 forEach 반복문으로 checkboxes 전체를 한번 싹 다 돌아줌

만약 checkbox가 지금 선택한 것 이거나 checkbox가 마지막 클릭했던 check박스 이면

inBetween 속성을 true ⇒ false, false ⇒ true로 바꿔줌

바꿔준 후 다른 if를 타는데 inBetween이 true면 checkbox.checked 속성을 true로 바꿔 체크 되게 함