이벤트 버블링
브라우저 내에서 한 요소에 이벤트가 발생하면, 이 요소에 할당된 핸들러가 동작하고, 이어서 부모 요소의 핸들러가 동작합니다. 가장 최상단의 조상 요소를 만날 때까지 이 과정이 반복되면서 요소 각각에 할당된 핸들러가 동작합니다. 이러한 현상을 이벤트 버블링이라고 합니다.
위와 같은 형태를 가진 웹 페이지가 있다고 가정해보겠습니다.
위의 main, section, div, p 태그는 계층관계를 가지고 있습니다.
이 때 해당 요소들의 click 이벤트를 감지하는 리스너를 등록합니다.
이 때 위의 p 태그를 클릭했을 시에 어떤 일이 발생할까요?
위와 같이 콘솔에 clicked!가 4번 출력됩니다.
이렇듯, p 태그의 이벤트가 동작하고 p 태그와 계층 관계에서 부모 관계를 가지고 있는 div, section, main 태그에 이벤트 핸들러에 등록된 콜백 함수 까지 동작하는 현상을 이벤트 버블링이라고 합니다.
이러한 이벤트 버블링 현상은 해당 이벤트가 발생한 요소에서 자신의 계층 관계에서 부모 요소에게 계속 전이됩니다.
하지만 해당 현상은 이벤트 객체의 메서드인 event.stopPropagtion()을 통해 임의적으로 중단시킬 수 있습니다.
위와 같이 div 태그에 event.stopPropagation() 메서드를 사용한 후 p 태그를 클릭하면
p 태그와 div 태그 까지 이벤트 핸들러가 동작하고 이벤트 버블링이 중지되어 div 태그의 부모들의 이벤트 핸들러는 동작하지 않습니다.
하지만 브라우저의 이벤트 버블링 현상은 자연스러운 것으로, 이벤트 버블링 중지가 꼭 필요한 특별한 경우가 아니라면 막는 것을 권장하지 않는다고 합니다.
이벤트 캡쳐링
이벤트 캡쳐링은 이벤트 버블링과는 정확히 반대로, 해당 이벤트가 발생한 요소의 최상단 계층에 요소 부터 하위 계층으로 내려오는 것을 말합니다. 실제 코드에서 자주 쓰이진 않지만, 종종 유용한 경우가 있으므로 알아두는 게 좋다고 합니다.
이벤트 캡쳐링은 일반적인 상황에서 발생하지 않고, addEventListener의 세번째 인수로 { capture : true || false} 로 설정할 수 있습니다.
위와 같이 console.log의 값들을 살짝 바꾸고, main에 addEventListener의 세번째 인수로 { capture : true }라는 설정 값을 전달해보겠습니다.
그리고 위와 같이 p 태그를 클릭하게 되면,
main 태그는 캡쳐링의 플로우(상위에서 하위로)에 동작하기 때문에 가장 먼저 출력되고,
나머지 capture 옵션 값이 지정되지 않은 태그들은 버블링의 플로우로 동작합니다.
이 때 div 태그에 event.stopPropagation()을 사용해보겠습니다.
위와 같이 출력됩니다.
이러한 플로우를 자세하게 설명하자면,
1. p 태그의 이벤트가 발생하고, 우선 캡쳐링의 플로우를 따라갑니다. 이 때 main 태그에 true 옵션을 감지하여 main 태그의 이벤트 핸들러가 동작합니다.
2. 맨 아래 계층의 요소까지 캡쳐링의 플로우로 탐색하지만, capture : true가 없기 때문에 탐색을 종료합니다.
3. 버블링의 플로우로 탐색을 시작합니다. 이벤트가 발생한 p 태그의 핸들러가 동작하고 상위 태그로 이동합니다.
4. 버블링으로 p 태그가 동작하고 상위 태그인 div 태그의 이벤트 핸들러가 동작합니다. 이 때 console.log를 출력하고, event.stopPropagation() 메서드가 동작하여 버블링 탐색을 중지합니다.
'WEB > JAVASCRIPT' 카테고리의 다른 글
이터러블(Iterable)과 이터레이터(Iterator) (0) | 2025.05.02 |
---|---|
자바스크립트의 모듈 시스템 (CommonJS, ES Module) (0) | 2025.01.12 |
Promise, 프로미스 (0) | 2024.02.03 |
Rest 파라미터, 스프레드 문법 (0) | 2023.04.10 |
클로저 (0) | 2023.02.15 |