본문 바로가기

WEB/JavaScript

[JS] 이벤트 버블링과 캡처링

중첩된 엘리먼트들 중 어느 한 요소에 이벤트 핸들러를 등록하면 중첩된 엘리먼트들 모두 전파되는 현상을 말한다.

이런 현상을 HTML DOM API의 이벤트 전파(Event Propagation)라 말하고 두 가지 방식으로 구분된다.

  1. 이벤트 버블링 : 이벤트가 발생한 요소부터 window 까지 이벤트를 전파한다.(👆)
  2. 이벤트 캡처링 : window 로부터 이벤트가 발생한 요소까지 이벤트를 전파한다.(👇)

둘의 차이는 방향에 있다. 상위 계층요소에서 하위로 간다면 이벤트 캡처링 그 반대인 하위 요소에서 상위 계층요소로 전파된다면 그것을 이벤트 버블링이라고 말한다.

이벤트 버블링

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

 

 

위 html과 JS를 렌더링 후에 div 태그 한 개만 클릭하면 왜 3개의 이벤트가 발생되는 걸까요?

그 이유는 브라우저가 이벤트를 감지하는 방식 때문입니다.

브라우저는 특정 화면 요소에서 이벤트가 발생했을 때 그 이벤트를 최상위에 있는 화면 요소까지 이벤트를 전파시킵니다.

따라서, 클래스 명 three -> two -> one 순서로 div 태그에 등록된 이벤트들이 실행됩니다. 마찬가지로 two 클래스를 갖는 두 번째 태그를 클릭했다면 two -> one 순으로 클릭 이벤트가 동작하겠죠.

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

이벤트 캡처링

이벤트 버블링에서 방향만 바뀐 형태이다.

하위 요소를 클릭하면 상위 요소까지 이벤트가 전파되는 현상이 일어난다.

해결법

이벤트 버블링과 캡처링은 특징이지 절때 에러가 아니다.

하지만 이런 현상은 웹 개발할때 구현을 방해하는 요소가 되기도 한다. 그럴때 해결할 방법은

 

WEB API중 하나인 event.stopPropagation()를 사용하는 방법이다.

사용 방법은 간단하다.

이벤트를 발생시키고 버블링 혹은 캡처링이 일어나지 않도록 하는 요소에

// 이벤트 버블링 예제
divs.forEach(function(div) {
	div.addEventListener('click', logEvent);
});

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

위 코드와 이벤트가 실행되는 함수에 작성만 해주면된다..

캡처링에 경우에는 이벤트 핸들러를 부여할때 capture : true를 추가해주면 된다.

 

https://joshua1988.github.io/web-development/javascript/event-propagation-delegation/#%EC%9D%B4%EB%B2%A4%ED%8A%B8-%EB%B2%84%EB%B8%94%EB%A7%81---event-bubbling

'WEB > JavaScript' 카테고리의 다른 글

[JS] Formik  (0) 2021.06.13
[JS] 함수를 호출하는 call / apply / bind 차이점  (0) 2021.06.08
[JS] 이벤트 루프(Event Loop)  (0) 2021.06.07
[JS] 자바스크립트 동작원리  (0) 2021.06.07
[JS] 메모리 힙과 콜스택  (0) 2021.06.07