[JS] 이벤트 위임

HP :) 😃·2022년 8월 17일
2
post-thumbnail

안녕하세요 hp 입니다 :)

오늘은 지난 포스팅에 연장선인 이벤트 위임( event delegation )에 대해서 공부해보겠습니다.

📚 개념

이벤트 위임이란 사용자의 액션에 의해 이벤트 발생 시 이벤트 버블링에 의해 document 레벨까지 버블링 되어 올라가는데 이 때문에 자식 엘리먼트에서 발생하는 이벤트를 부모 엘리먼트에서도 감지할 수 있습니다. 이러한 작동 방식을 이용해 자식 엘리먼트의 하나하나에 모든 이벤트를 주는 것이 아닌 부모에게만 이벤트를 위임하는 방법입니다.

아래 예시를 통해서 이벤트 위임에 대해서 자세히 알아보겠습니다.

<!-- 이벤트 위임 -->
<html>
  <body>
    <div class="menu">
      <button class="items">첫번째 버튼</button>
      <button class="items">두번째 버튼</button>
      <button class="items">세번째 버튼</button>
    </div>
    <script>
      for (const item of document.querySelectorAll(".items")) {
        item.addEventListener("click", (e) => {
          alert(`${e.target.innerText}입니다.`);
        });
      }
    </script>
  </body>
</html>

만일 우리가 위와 같이 button에게 click event를 전달하여 몇번째 버튼인지 확인하는 코드를 작성한다고 했을때 우리는 button의 갯수에 따라서 for문을 돌리고 addEventListener를 통해 click 이벤트를 전달할 것입니다.

위와 같은 방식은 addEventListener를 여러번 호출하여 메모리 측면에서 비효율적이고 성능이 떨어질 수 있습니다.

따라서 우리는 이벤트 버블링을 활용하여 부모 엘리먼트에게 이벤트를 위임하는 코드를 작성해줍니다.

<!-- 이벤트 위임 -->
<html>
  <body>
    <div class="menu">
      <button class="items">첫번째 버튼</button>
      <button class="items">두번째 버튼</button>
      <button class="items">세번째 버튼</button>
    </div>
    <script>
      const menu = document.querySelector(".menu");
      menu.addEventListener("click", (e) => {
        alert(`${e.target.innerText}입니다.`);
      });
    </script>
  </body>
</html>

위와 같이 menu(부모 엘리먼트)button(자식 엘리먼트)의 event를 전달해줌으로써 한번의 이벤트 생성으로 효율적으로 코드를 작성할 수 있습니다.

이벤트 위임의 장점에는 여러가지가 있습니다.

  1. 동적인 엘리먼트에 대한 이벤트 처리가 수월합니다.
  2. 상위 엘리먼트에서만 이벤트를 관리하기 때문에 하위 엘리먼트는 자유롭게 추가 삭제할 수 있습니다.
  3. 메모리 사용량이 줄어듭니다.
  4. 동일한 이벤트에 대해 한 곳에서 관리하기 때문에 각각의 엘리먼트를 여러 곳에 등록하여 관리하는 것보다 수월합니다.

⚒️ 동적 엘리먼트 생성

이벤트 위임은 동적인 엘리먼트에 대한 이벤트를 관리할때 굉장히 효율적입니다.

아래 예시를 통해 살펴보겠습니다.

<!-- 동적인 이벤트 위임 -->
<!DOCTYPE html>
<html>
  <body>
    <button class="create">CREATE</button>
    <div class="menu">
      <button class="items">첫번째 버튼</button>
      <button class="items">두번째 버튼</button>
      <button class="items">세번째 버튼</button>
    </div>
    <script>
      const menu = document.querySelector(".menu");
      const create = document.querySelector(".create");

      create.addEventListener("click", () => {
        menu.innerHTML += `
          <button class="items">네번째 버튼</button>
          <button class="items">다섯번째 버튼</button>
        `;
      });

      for (const item of document.querySelectorAll(".items")) {
        item.addEventListener("click", (e) => {
          alert(`${e.target.innerText}입니다.`);
        });
      }
    </script>
  </body>
</html>

위와 같이 create 버튼으로 네번째 , 다섯번째를 생성하고 네번째 , 다섯번째의 버튼을 클릭했을시 alert창이 뜨기를 기대하지만 이벤트 리스너가 등록되는 시점에서는 기존의 3개의 아이템만 존재하기 때문에 작동되지 않습니다.

이때 이벤트 위임 방식을 이용하여 부모 엘리먼트인 menu에 이벤트 등록을 시켜주면 모든 버튼이 이벤트를 감지할 수 있습니다.

<!-- 동적인 이벤트 위임 -->
<html>
  <body>
    <button class="create">CREATE</button>
    <div class="menu">
      <button class="items">첫번째 버튼</button>
      <button class="items">두번째 버튼</button>
      <button class="items">세번째 버튼</button>
    </div>
    <script>
      const menu = document.querySelector(".menu");
      const create = document.querySelector(".create");

      create.addEventListener("click", () => {
        menu.innerHTML += `
          <button class="items">네번째 버튼</button>
          <button class="items">다섯번째 버튼</button>
        `;
      });

      menu.addEventListener("click", (e) => {
        alert(`${e.target.innerText}입니다.`);
      });
    </script>
  </body>
</html>

끝까지 읽어주셔서 감사합니다. 😃

📌 참고

코어 자바스크립트 이벤트 위임
TOAST UI 이벤트 위임

profile
끊임없이 노력하는 개발자

0개의 댓글