Event Prevent & Event delegation

Event Prevent

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      div {
        width: 250px;
        height: 250px;
        background-color: yellow;
        margin-bottom: 5px;
      }
    </style>
  </head>
  <body>
    <div>
      <input type="checkbox" />
    </div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <script>
      document.addEventListener('wheel', event => {
        console.log('scrolling');
        event.preventDefault();
      },
      {passive: false} // 브라우저가 스크롤링 되는 걸 막을수 있으나, 사용 안하는 것이 좋음
      );
      const checkbox = document.querySelector('input');
      checkbox.addEventListener('click', event => {
        // long
        console.log('checked');
        event.preventDefault(); // 브라우저가 기본적으로 해야할 행동을 막음
      });
    </script>
  </body>
</html>

Event Delegation

버블링업 되는 것을 이용하여 delegation(이벤트 위임)을 해보자

✏️ 클릭되었을때 노란으로 바뀌는 코드를 작성해보자.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      .selected {
        background-color: yellow;
      }
    </style>
  </head>
  <body>
    <ul>
      <li>1</li>
      <li>2</li>
      <li>3</li>
      <li>4</li>
      <li>5</li>
      <li>6</li>
      <li>7</li>
      <li>8</li>
      <li>9</li>
      <li>10</li>
    </ul>
    <script>
      // Bad 🚫
      // const lis = document.querySelectorAll('li');
      // lis.forEach(li => {
      //   li.addEventListener('click', () => {
      //     li.classList.add('selected');
      //   });
      // });
      // 보통 내가 사용하던 방법 .. 😞



      // Coooooooool 🙌
      const ul = document.querySelector('ul');
      ul.addEventListener('click', event => {
        if (event.target.tagName == 'LI') {
          event.target.classList.add('selected');
        }
      });
    </script>
  </body>
</html>

보통 li태그들을 다 querySelectorAll()로 가져와서 각 엘리멘트에 이벤트 리스너를 붙이는데, bubbling을 이용하여 ul 하나에만 이벤트 리스너를 붙여 처리할 수 있다.

이렇게 부모 안에 있는 자식들에게 공통적으로 무언가 처리해야할 때 일일이 이벤트 리스너를 자식 노드에 추가하는 것보다, event의 타겟을 이용하여 부모에 등록하는것이 좋다.