Web-Frontend/JavaScript

[JS] 이벤트의 전파와 흐름 (이벤트 버블링, 캡처링, 위임)

서노리 2023. 10. 2. 19:03
반응형

본문에 들어가기 앞서 이벤트 등록에 대해 알고 있어야한다.

<button>아이템 추가</button>
const button = document.querySelector('button');
button.addEventListener('click', addItem);

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

위 코드는 버튼을 클릭했을 때 addItem이라는 함수가 실행되도록 하는 코드이다. 이와 같이 addEventListener()를 통해 HTML 요소에 동적인 기능을 추가할 수 있게 된다. 여기서 브라우저는 어떻게 이벤트의 발생을 감지하게 되는지 알아보자


이벤트 버블링 - Event Bubbling

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

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

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

위 코드는 세 개의 div 태그에 모두 클릭 이벤트를 등록하고 클릭 했을 때 해당 요소의 className을 출력하는 logEvent 함수를 실행시키는 코드이다. 여기서 최하위 div 태그인 <div class="three"></div>를 클릭하면 다음과 같은 결과가 나온다.

div 태그 하나만 클릭했을 뿐인데 3개의 이벤트가 발생하는 모습을 볼 수 있다. 

그 이유가 바로 브라우저가 이벤트를 감지하는 기본 방식인 이벤트 버블링 때문이다.

거의 모든 이벤트는 버블링이 이루어진다. 다만, focus 이벤트와 같이 버블링 되지 않는 이벤트도 존재한다.


이벤트 캡처링 - Event Capturing

이벤트 캡처링은 이벤트가 발생했을 때 해당 이벤트가 최상위 요소인 body부터 해당 이벤트가 발생한 태그까지 전달되며 내려가는 특성이다.

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

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

브라우저의 이벤트 전파 방식은 버블링이 기본 값이기 때문에 캡처링으로 설정하기 위해서는 addEventListener 함수의 3번째 매개변수로 capture: true 값을 주면 이 이벤트 타겟은 캡처링을 통해 이벤트를 전파받아 호출되게 된다.

 

따라서 아까와 동일하게 최하위 div 태그인 <div class="three"></div>를 클릭해도 위와 같이 버블링과 반대 결과가 출력되는 것을 볼 수 있다.


이벤트 전파가 있는 이유

1. 논리적인 이유

자식 요소가 부모 요소 안에 위치하고 있기 때문에 자식 요소만을 클릭하더라도 다른 시각으로 보면 부모 요소도 클릭한 것과 마찬가지이다.

 

2. 성능적인 이유

이벤트 전파라는 특징 때문에 이벤트 등록 코드를 줄일 수 있다는 장점도 있다.

<ul id="post-list">
    <li id="post-1">Item 1</li>
    <li id="post-2">Item 2</li>
    <li id="post-3">Item 3</li>
    <li id="post-4">Item 4</li>
    <li id="post-5">Item 5</li>
    <li id="post-6">Item 6</li>
</ul>

위와 같은 코드에서 어떠한 요소를 클릭해도 이벤트를 발생시키고 싶다고 하자. 이벤트 전파 개념이 없다면, <li> 태그마다 일일히 이벤트를 등록해야하는 귀찮은 일이 발생한다. 하지만 버블링의 특성을 통해 부모 요소인 <ul> 요소에만 이벤트를 등록하면, 어떤 <li> 태그를 클릭하더라도 부모 요소로 이벤트가 전파되기 때문에 더욱 코드를 간단하게 작성할 수 있다.

이러한 기법을 이벤트 위임이라고 부른다.


 

반응형