새오의 개발 기록

Javascript: 이벤트 버블링과 캡쳐 본문

Javascript

Javascript: 이벤트 버블링과 캡쳐

새오: 2022. 9. 28. 19:29

오늘은 이벤트 버블링과 캡쳐에 대해 정리해보려고 하는데요.

그 전에 순수 JS를 다뤄본 게 너무 오래 전이라 이벤트 등록 방법 부터 짚어보려고 합니다.

 

 

 

 

JS에서의 이벤트 등록

 

이벤트 등록은 사용자의 입력을 받기 위한 기능입니다.

 

<button>add one item</button>

 

click me 라는 버튼이 있습니다.

 

var button = document.querySelector('button');
button.addEventListener('click', addItem);

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

 

버튼을 클릭하면 addItem 함수가 실행되고 addItem 함수에 event 인자가 넘어옵니다.

event 인자를 콘솔에 출력해보면 이벤트와 관련된 정보를 확인할 수 있습니다.

 

여기서 사용되는 addEventListener 는 웹 개발자들이 화면에 동적인 기능(여기서는 버튼 클릭)을 추가하기 위해 

기본적으로 사용하는 웹 API 입니다.

 

그렇다면 브라우저는 동적인 기능, 즉 이벤트의 발생을 어떻게 감지했을지를

이벤트 버블링과 캡쳐링의 두 방식으로 알아보겠습니다.

 

 

 

 

 

 

이벤트 버블링(Event Bubbling)

 

이벤트 버블링은 한 요소에 이벤트가 발생하면 해당 이벤트가 보다 상위의 요소로 전달되어 가는 특성을 의미합니다.

HTML은 기본적으로 트리 구조를 갖기 때문에 계속 상위로 이동하다보면 body 태그까지 도달하게 됩니다.

 

https://joshua1988.github.io/web-development/javascript/event-propagation-delegation/

 

 

 

이 그림을 코드를 통해 보면

<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);
}



// 결과

// three
// two
// one

 

 

최하위의 <div class="three"></div>를 클릭했을 때 

three

two

one 의 순서로 콘솔창에 출력됩니다.

 

모든 div 태그에 대해 이벤트가 등록되어 있기 때문에

상위의 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);
}

// 결과

// one
// two
// three

 

 

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

따라서, 아까와 동일하게 <div class="three"></div> 를 클릭하면

 

one

two

three

 

 순으로 결과가 출력되게 됩니다.

 

 

 

 

참고

https://joshua1988.github.io/web-development/javascript/event-propagation-delegation/

'Javascript' 카테고리의 다른 글

Javascript: Array.fill()  (0) 2023.01.14
Javascript: fs 모듈로 입력 받기  (0) 2023.01.12
javascript: hoisting 호이스팅  (0) 2022.10.03
Javascript: 비동기 처리  (0) 2022.09.28
Javascript: 동기와 비동기의 차이  (0) 2022.09.27