이벤트 버블링과 이벤트 캡처링

김철준·2023년 3월 12일
0

Javascript

목록 보기
13/16

DOM 트리 상에 존재하는 DOM 요소 노드에서 발생한 이벤트는 DOM 트리를 통해 전파됩니다.

이를 이벤트 전파라고 하는데요.
생성된 이벤트 객체는 이벤트를 발생시킨 DOM 요소인 이벤트 타켓을 중심으로 DOM 트리를 통해 전파됩니다.

이벤트 전파 방향에 따라 이벤트 버블링과 캡처링을 구분하는데요.

이벤트 버블링

이벤트 버블링은 이벤트 타켓으로부터 상위 요소 방향으로 window 객체까지 이벤트 객체가 전파되는 방식입니다.


<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <ul id="fruits">
      <li id="apple">사과</li>
      <li id="banana">바나나</li>
      <li id="orange">오렌지</li>
    </ul>
    <script src="./event.js"></script>
  </body>
</html>

만약 banana li 요소를 클릭하면 해당 이벤트 타켓으로부터 시작하여 클릭 이벤트 객체가 window 객체까지 올라가게 됩니다.

이벤트 전파 방향
<li id="banana">바나나</li> => <ul> => <body> => <html> => <document> => <window>

이벤트 캡처링

이벤트 캡처링은 최상위 전역 객체 Window 객체로부터 이벤트 타겟까지 하위 요소 방향으로 이벤트 객체가 전파되는 방식입니다.


<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <ul id="fruits">
      <li id="apple">사과</li>
      <li id="banana">바나나</li>
      <li id="orange">오렌지</li>
    </ul>
    <script src="./event.js"></script>
  </body>
</html>

이벤트 전파 방향
<window> => <document> => <html> => <body> => <ul> =><li id="banana">바나나</li>

이를 활용하면 어떤 장점이 있을까?

이벤트 버블링과 캡처링을 활용하면 이벤트를 발생시킨 이벤트 타깃은 물론 상위 DOM 요소에서도 이벤트 객체를 캐치할 수 있습니다.

이를 활용하면 이벤트를 발생시킨 이벤트 타킷은 물론 상위 DOM 요소에서도 이벤트 객체를 캐치할 수 있습니다.

그리하여 이벤트 버블링과 캡처링을 활용하면 다음과 같은 장점이 있습니다.

  • 이벤트 핸들러의 중복 방지

여러 개의 하위 요소에 동일한 이벤트 핸들러를 등록할 경우, 이벤트 버블링을 이용하여 상위 요소에서 이벤트를 처리할 경우 중복 코드를 제거할 수 있습니다.

예를 들어, 여러 하위 요소에서 클릭 이벤트를 처리하도록 했다고 해봅시다.
모든 하위 요소에 클릭 이벤트 리스너를 붙여줘야합니다.

이는 코드의 중복성을 발생시킵니다.

<div class="parent">
  <div class="child1">
    <button class="btn1">버튼1</button>
  </div>
  <div class="child2">
    <button class="btn2">버튼2</button>
  </div>
</div>
const btn1 = document.querySelector('.btn1');
btn1.addEventListener('click', () => {
  console.log('버튼1 클릭됨');
});

const btn2 = document.querySelector('.btn2');
btn2.addEventListener('click', () => {
  console.log('버튼2 클릭됨');
});

버튼 1과 버튼 2는 둘 다 클릭 이벤트를 사용하기 때문에 각각의 버튼에 클릭 이벤트를 붙여줍니다.

하지만 이벤트 버블링을 활용하면 상위 요소에 위임할 수 있습니다.

const parent = document.querySelector('.parent');
parent.addEventListener('click', (event) => {
  const target = event.target;
  if (target.classList.contains('btn1')) {
    console.log('버튼1 클릭됨');
  } else if (target.classList.contains('btn2')) {
    console.log('버튼2 클릭됨');
  }
});

parent라는 요소에 클릭 이벤트를 붙여주고 클릭 target 이벤트를 캐치하여 조건에 따라 로직을 구현해주면 됩니다.

이처럼 상위 요소에 이벤트를 위임하여 코드의 중복을 줄여 간결화할 수 있습니다.

  • 코드 간결성
    이벤트 핸들러를 상위 요소에서 처리할 경우, 하위 요소에서 이벤트 핸들러를 등록하는 것보다 더 간결한 코드를 작성할 수 있습니다.

위 예시에서 봤던 것처럼 두 개의 이벤트 리스너를 붙일 필요없이 상위 요소에 이벤트 하나만 붙임으로써 코드를 간결하게 할 수 있습니다.

  • 동적 이벤트 처리
    이벤트 버블링을 이용하여 상위 요소에서 이벤트를 처리할 경우, 새로운 하위 요소가 추가되어도 추가적인 이벤트 핸들러 등록 없이 상위 요소에서 이벤트를 처리할 수 있습니다.

위 예제에서 만약 버튼이 4개 더 추가되었다고 해봅시다.
그렇다면 각 버튼에 클릭 이벤트를 붙일 필요없이 각 버튼을 클래스로 구분하고 해당 버튼의 조건부에 따라 로직만 구현해주면 됩니다.

마무리

이처럼 이벤트 버블링과 캡처링을 활용하여 상위 요소에서 이벤트를 처리하는 것은 코드의 효율성과 가독성을 높일 수 있으며, 유지보수도 더욱 용이해집니다.

여러 요소에 같은 이벤트를 붙일 상황이 있을 때 하나의 상위 요소에서 처리할 수 있을지 고민해보고 처리할 수 있다면 이벤트 버블링 캡처링을 사용해야겠습니다.

profile
FE DEVELOPER

0개의 댓글