Programming/Javascript

[JavaScript] 이벤트 버블링과 이벤트 캡쳐링을 알아보자

cbw1030 2020. 12. 28. 20:49
반응형

 

자바스크립트에서 이벤트를 전달하는 방식은 버블링, 캡쳐, 위임 방식이 있습니다.

이번 포스팅에서는 이벤트 버블링, 캡쳐링에 대해 알아보겠습니다.

 

이벤트 버블링

버블링은 거품이 커져가는 뉘앙스가 담겨 있습니다. 거품이 위로 많아지는 경우를 생각하면 이해하기 쉽습니다.

이벤트 버블링은 어떤 요소에 대해 이벤트가 발생했을 때, 해당 요소의 최상위 부모까지 이벤트가 전달되어지는 과정을 의미합니다.

 

https://www.javascripttutorial.net/javascript-dom/javascript-events/

예시를 하나 들어보겠습니다.

<div class="grand-parent">
    <div class="parent">
        <div class="son"></div>
    </div>
</div>

노란색은 son, 파란색은 parent, 빨간색은 grand-parent 부분입니다.

 

그리고 다음과 같은 js 소스코드가 있습니다.

var grandParent = document.querySelector('.grand-parent');
var parent = document.querySelector('.parent');
var son = document.querySelector('.son');

grandParent.addEventListener('click', function(e) {
    console.log('grand-parent');
});

parent.addEventListener('click', function(e) {
    console.log('parent');
});

son.addEventListener('click', function(e) {
    console.log('son');
});

이 상태에서 노란색 박스(son)를 클릭하면 콘솔탭에 무엇이 찍힐까요?

 

son -> parent -> grand-parent가 순서대로 찍혔습니다.

 

분명히 노란색 박스만 클릭했지만 parent, grand-parent까지 출력되는 이유는 이벤트 버블링 때문입니다.

 

만약 파란색 박스(parent)를 클릭한다면 다음과 같습니다.

당연한 결과입니다. 파란색 박스부터 상위 요소(grand-parent)로 이벤트가 전달되어지기 때문이죠.

 

 

 

이벤트 캡쳐링

이벤트 캡쳐링은 이벤트 버블링과 정반대입니다.

 

이벤트 버블링이 어떤 요소에 대해 이벤트가 발생했을 때 해당 요소의 최상위 부모까지 이벤트가 전달되어지는 과정을 의미한다면, 이벤트 캡쳐링은 어떤 요소에 대해 이벤트가 발생했을 때 최상위 부모로부터 이벤트가 발생된 요소까지 이벤트가 전달되어지는 과정을 의미합니다.

 

https://www.javascripttutorial.net/javascript-dom/javascript-events/

 

이벤트 캡쳐링을 하기 위해서는 addEventListener의 세 번째 인자를 true로 설정해야 합니다.

 

addEventListener의 원형은 다음과 같습니다.  developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener

target.addEventListener(type, listener [, useCapture]);

addEventListener의 세 번째 인자를 아예 쓰지 않거나 false로 설정한다면 '이벤트 버블링'을 하겠다는 의미이고 true로 설정한다면 '이벤트 캡쳐링'을 하겠다는 의미입니다.

 

var grandParent = document.querySelector('.grand-parent');
var parent = document.querySelector('.parent');
var son = document.querySelector('.son');

grandParent.addEventListener('click', function(e) {
    console.log('grand-parent');
}, true);

parent.addEventListener('click', function(e) {
    console.log('parent');
}, true);

son.addEventListener('click', function(e) {
    console.log('son');
}, true);

 

이 상태에서 노란색 박스(son)을 클릭하면 콘솔탭에 어떤 것이 출력될까요?

이벤트 캡쳐링으로 인해 grand-parent, parent, son 순으로 출력이 됩니다.

 

 

e.stopPropagation( )

버블링과 캡쳐링을 이해했다면 다음과 같은 생각이 들 수 있습니다.

 

'나는 노란색 박스(son)부분만 클릭했을 때 노란색 박스의 이벤트만 실행되고 캡쳐링이든 버블링이든 다른 요소들의 이벤트는 실행안됐으면 좋겠는데 방법이 없을까?'

 

e.stopPropagation 함수를 사용하시면 위의 질문의 답이 되실겁니다.

 

버블링, 캡쳐링에 모두 적용되는 내용이니 캡쳐링 부분의 예제에 적용하여 보여드리겠습니다.

 

var grandParent = document.querySelector('.grand-parent');
var parent = document.querySelector('.parent');
var son = document.querySelector('.son');

grandParent.addEventListener('click', function(e) {
    console.log('grand-parent');
    e.stopPropagation();
}, true);

parent.addEventListener('click', function(e) {
    console.log('parent');
}, true);

son.addEventListener('click', function(e) {
    console.log('son');
}, true);

이 상태에서 son을 클릭한다면 어떻게 될까요?

e.stopPropagation을 호출하지 않았다면 grand-parent -> parent -> son이 순서대로 출력됐겠지만, e.stopPropagation을 호출했기 때문에 grand-parent만 호출하고 하위 요소에 있는 이벤트들은 실행되지 않고 멈춘 것을 확인하실 수 있습니다.

 

 

반응형