[기술면접] 이벤트 버블링과 이벤트 캡쳐란

윤후·2022년 6월 27일
1

기술면접

목록 보기
20/28
post-custom-banner

이벤트

이벤트 등록

이벤트 버블링의 현상을 알기 위해 먼저 이해하고 있어야 하는 내용은 바로 웹 애플리케이션의 이벤트 등록이다. 여기서 말하는 이벤트 등록이란 웹 애플리케이션에서 사용자의 입력을 받기 위해 필요한 기능이다. 아래의 코드를 봐보자.

<button>add one item</button>
var button = document.querySelector('button');
button.addEventListener('click', addItem);

function addItem(event) {
	console.log(event);
}

add one item이라는 간단한 버튼을 만들어 클릭했을 때, additem이라는 함수를 실행시키는 코드이다. 버튼을 클릭하고 나면 additem 함수가 실행되고 additem 함수에 event인자가 넘어온다. event인자를 콘솔에 출력해보면 이벤트와 관련된 정보를 확인할 수 있다.

이처럼 addEventListener()웹 API는 웹 개발자들이 화면에 동적인 기능을 추가하기 위해 자연스럽게 접하게 되는 기본적인 기능이다. 사용자의 입력에 따라 추가 동작을 구현할 수 있는 방법이다. 여기서 브라우저는 어떻게 이벤트의 발생을 감지했을까? 브라우저가 이벤트를 감시하는 방식을 알아보자.

이벤트 버블링 (Event Bubbling)

이벤트 버블링은 특정 화면 요소에서 이벤트가 발생했을 때 해당 이벤트가 더 *상위의 화면 요소들로 전달되어가는 특성을 의미한다.

*상위의 화면 요소란?
HTML 요소는 기본적으로 트리구조를 갖는다. 여기서는 트리 구조상으로 한 단계 위에 있는 요소를 상위 요소라고 하며 body태그를 최상위 요소라고 부르겠다.

위의 그림은 아래의 예시코드를 미리 도식화한 그림이다. 세 개의 div태그가 있고 가장 아래에 있는 div태그에서 이벤트가 발생했을 때 최상위 요소인 body태그까지 이벤트가 전달된는 모습을 나타냈다.

<body>
	<div class="one">
		<div class="two">
			<div class="three">
			</div>
		</div>
	</div>
</body>
var divs = document.querySelectorAll('div');
divs.forEach(function(div) {
	div.addEventListener('click', logEvent);
});

function logEvent(event) {
	console.log(event.currentTarget.className);
}

위의 코드는 세 개의 div태그에 모두 클릭 이벤트를 등록하고 클릭했을때 logEvent함수를 실행시키는 코드이다. 여기서 위 그림대로 최하위 div태그 <div class="three"><div>를 클릭하면 아래와 같은 결과가 실행된다.

div태그 한 개만 클릭했을 뿐인데 왜 3개의 이벤트가 발생하게 되는걸까? 그 이유는 브라우저가 이벤트를 감지하는 방식 때문이다.

브라우저는 특정화면 요소에서 이벤트가 발생했을 때 그 이벤트를 최상위에 있는 화면 요소까지 이벤트를 전파시킨다. 따라서 three -> two -> one순으로 클릭이벤트가 동작한다.

여기서 주의해야 할 점은 각 태그마다 이벤트가 등록되어 있기 때문에 상위 요소로 이벤트가 전달되는 것을 확인할 수 있다. 만약 이벤트가 특정 div태그에만 달려 있다면 위와 같은 동작 경과는 확인할 수 없다.

이와 같은 하위에서 상위 요소로의 이벤트 전파 방식을 이벤트 버블링(Event Bubbling)이라고 한다.

이벤트 캡쳐 - Event Capture

이벤트 캡쳐는 이벤트 버블링과 반대 방향으로 진행되는 이벤트 전파 방식이다.

위 그림처럼 특정 이벤트가 발생했을 때 최상위 요소인 body태그에서 해당 태그를 찾아 내려간다. 그럼 이벤트 캡쳐는 코드로 어떻게 구현이 될까?

<body>
	<div class="one">
		<div class="two">
			<div class="three">
			</div>
		</div>
	</div>
</body>
var divs = document.querySelectorAll('div');
divs.forEach(function(div) {
	div.addEventListener('click', logEvent, {
		capture: true // default 값은 false입니다.
	});
});

function logEvent(event) {
	console.log(event.currentTarget.className);
}

addEventListener() API에서 옵션 객체에 capture:true를 설정해주면 된다. 그러면 해당 이벤트를 감지하기 위해 이벤트 버블링과 반대 방향으로 탐색한다.

따라서, 아까와 동일하게 <div class="three"></div> 를 클릭해도 아래와 같은 결과가 나타난다.

Reference
캡틴 판교
JavaScript Info

profile
궁금한걸 찾아보고 공부해 정리해두는 블로그입니다.
post-custom-banner

0개의 댓글