JavaScript

이벤트 버블링(Event Bubbling) 및 이벤트 캡처링(Event Capture)에 대해서

citron031 2023. 4. 26. 23:02

이벤트 버블링

이벤트 버블링은 한 요소에서 이벤트가 발생하였을 때, 해당 요소와 그 요소는 물론이고 그 요소의 모든 조상들에 연결된 이벤트가 모두 실행되는 것을 의미한다.

다음과 같은 예가 있다고 생각해보자.

<div id="container">
  Hello
  <span class="emoji"> 🫐 </span>
  World
</div>

위의 HTML은 div 내부에 span이 들어있는 구조이다.

#container {
  background: blue;
  color: white;
}

.emoji {
  background: red;
}

구분하기 쉽게 div요소는 파랑, 내부의 span은 빨간색의 배경을 가지게 한다.

const divContainer = document.querySelector('#container');

divContainer.addEventListener('click', () => {
  window.alert("HELLO WORLD")
})

const spanEmoji = document.querySelector('.emoji');

spanEmoji.addEventListener('click', () => {
  window.alert("HELLO " + "🫐");
})

그리고 다음과 같이 두 요소에 이벤트 핸들러를 연결했을 때, 무슨일이 일어나는가?

블루베리 이모지를 클릭하면 HELLO 🫐 알림창이 뜬 이후에 HELLO WORLD 알림창이 또 뜨는 것을 확인할 수 있다.

span의 이벤트 핸들러뿐만 아니라, 부모인 div에 연결된 이벤트 핸들러도 호출된 것이다.

 

focus와 같이 버블링이 일어나지 않는 이벤트도 있지만, 거의 모든 이벤트는 버블링이 일어난다.

버블링은 때로는 의도대로 동작하는 현상일 수 있지만, 때로는 아닐 수도 있다.

그런 경우 다음과 같이 이벤트 버블링을 막을 수 있다.

const divContainer = document.querySelector('#container');

divContainer.addEventListener('click', () => {
  window.alert("HELLO WORLD")
})

const spanEmoji = document.querySelector('.emoji');

spanEmoji.addEventListener('click', (event) => {
  event.stopPropagation()
  window.alert("HELLO " + "🫐");
})

event.stopPropagation() 가 추가된 뒤 다시 이모지를 클릭해보면, span에 연결된 이벤트 핸들러만이 호출되는 것을 알 수 있다.

🍅 event.stopImmediatePropagation() 를 사용하면, 부모뿐만 아니라 해당 요소에 연결된 다른 이벤트 핸들러의 동작도 막을 수 있다.

 

 

캡처링

버블링이 이벤트가 상위로 전파되는 것을 의미한다면, 캡처링은 이벤트가 하위로 전파되는 것을 의미한다.

캡처링은 addEventListener의 세 번째 인자를 true나 {capture: true}로 설정하여 활성화할 수 있다. 

 

기존에 버블링이 있는 상황에서 이모지를 누르면, 이모지가 있는 알림창이 뜬 뒤에 HELLO WORLD 알림칭이 뜬다.

즉, 하위에 요소에 연결된 이벤트 핸들러먼저 실행된 것이다.

const divContainer = document.querySelector("#container");

divContainer.addEventListener(
  "click",
  () => {
    window.alert("HELLO WORLD");
  },
  true
);

const spanEmoji = document.querySelector(".emoji");

spanEmoji.addEventListener(
  "click",
  (event) => {
    window.alert("HELLO " + "🫐");
  },
  true
);

반면에, 위와 같이 캡처링 설정을 한 뒤 이모지를 클릭해보면 다른 결과가 나오는 것을 확인할 수 있다.

이번엔 HELLO WORLD 알림창이 뜬 뒤에야 HELLO 🫐 알림창이 뜨는 것을 확인해볼 수 있다.

버블링과는 반대로 상위 요소의 이벤트 핸들러가 먼저 호출된 것이다.

 

🍰 event.target은 이벤트가 발생한 가장 아래쪽 요소를 가르킨다.

 

https://ko.javascript.info/bubbling-and-capturing

 

버블링과 캡처링

 

ko.javascript.info