본문 바로가기

Javascript

[자바스크립트] 이벤트 버블링과 이벤트 캡처링 쉽게 이해하기

서론 : 

이벤트 버블링과 이벤트 캡처링. 책을 읽으면 슥 이해하고 지나갔던 개념이다. 

최근 회사에서 이벤트 버블링에 관한 주제로 이야기가 오가는 것을 들은 적이 있는데, 

명확하게 이해하지 않고 넘어갔던 내가 생각났다.

그래서 조금 더 분명하게 정리해보고자, 이렇게 글을 쓰게 되었다. 

 

본론 : 

 

이벤트 버블링이란 ? : 

책을 통해 처음 접했을 땐 뭔소린고 했지만, 지금와서 생각해보니 생각보다 간단한 개념이었다. 

먼저 다음 그림을 보자. 

파란 -> 흰 -> 보라 순으로 nested된 div

위의 그림은 파란색 -> 흰색 -> 보라색 순으로 nesting 되어 있는 div들이다. 

이것을 코드로 확인해보면 아래와 같다. 

    <div class="puple">
        <div class="white">
            <div class="blue">
            </div>
        </div>
    </div>

위 코드에서 볼 수 있듯이, blue의 부모는 white, white의 부모는 puple이다. 

 

 

자, 이제 이렇게 nested된 박스를 가지고 무엇을 할 것이냐? 뭔저 각각의 div들에 console을 출력하는 핸들러를 등록하고,

가운데 있는 blue를 클릭해보자. 

여기서 중요한 포인트가 있다. 왜 blue를 클릭했는데, 다른 부모에 등록된 핸들러까지 작동이 되는 것일까? 대체 무슨 일이 일어난 것일까?! 

지금 여기서 발생하는 현상을 우리는 이벤트 버블링이라고 부른다. 

 

가장 깊숙이 내포되어 있는 자식요소를 클릭하면, 그 요소에서 부모요소까지 얽혀있는 모든 요소에 이벤트가 발생해, document까지 전달되는 현상을 이벤트 버블링이라고 부른다. 

 

이를 그림으로 이해하면 다음과 같다. 

가장 깊숙이 있는 blue div에서부터 white -> puple에게까지 버블링이 전파되는 것을 설명하는 그림이다. 

이런 동작 방식 때문에 가장 깊숙이 있는 div에서부터 차례대로 부모 div에게까지 이벤트가 전파되는 것이다. 

이런 흐름을 이벤트 버블링이라고 부른다. 가장 아랫속에서부터 부모를 거슬러 올라가 발생하는 모양이 꼭 버블(bubble)을 닮았기 때문이다. 

 

 

이벤트 캡처링 : 

 

그렇다면 이벤트 캡처링은 무엇을 말하는 것일까? 이벤트 버블링과 반대되는 개념이라고 생각하면 된다. 이벤트 버블링은 현재 이벤트가 발생한 곳에서부터 부모로 전파되는 것이라면, 이벤트 캡쳐링은 부모에서부터 현재 클릭된 요소까지 전파되는 것이라고 생각하면 된다. 

 

아래처럼 이벤트 캡처링을 등록해서 과정을 확인해보도록 하자. 참고로 addEventListener의 세번째 인자로 이벤트 캡쳐링의 여부를 전달할 수 있다. 기본 값이 false로 되어있기 때문에 세번째 인자에 true를 넘겨주면 캡처링의 동작을 볼 수 있다. 


        const blue = document.querySelector(".blue");
        const white = document.querySelector('.white');
        const puple = document.querySelector('.puple');

        blue.addEventListener('click', (e) =>
            console.log('%c blue가 클릭되었다. ', 'color: black; background-color: rgb(78, 78, 236);'),
            true
        )
        white.addEventListener('click', (e) =>
            console.log('%c white가 클릭되었다. ', 'color: black; background-color: white;'),
            true
        )
        puple.addEventListener('click', (e) =>
            console.log('%c puple이 클릭되었다. ', 'color: black; background-color: rgb(161, 71, 189);'),
            true
        )

세번째 인자로 캡처링의 여부를 true로 넘겨주었다. 


그리고 실제로 동작하는 모습을 확인해보자. 

 

위에 보이는 gif 영상처럼 blue를 클릭했더니, 현재로써 가장 부모에 속해있던 div에서부터 아래로 흘러오면서 핸들러가 작동하는 것을 확인할 수 있다. 

 

이렇게 이벤트가 하위로 전파되는 단계를 우리는 캡처링 단계라고 부른다.