이벤트 버블링(Event Bubbling) 및 이벤트 캡처링(Event Capture)에 대해서
이벤트 버블링
이벤트 버블링은 한 요소에서 이벤트가 발생하였을 때, 해당 요소와 그 요소는 물론이고 그 요소의 모든 조상들에 연결된 이벤트가 모두 실행되는 것을 의미한다.
다음과 같은 예가 있다고 생각해보자.
<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