[JavaScript] 이벤트 위임과 버블링

정예원·2021년 8월 29일
0

JavaScript

목록 보기
3/13
post-custom-banner

강의를 듣던 중 이벤트 버블링을 다루었다.
이전에 공부했지만 또 다시 잊어버린 나😉 반성하며 다시 정리해보자!

이벤트 위임이 뭐야?

이벤트를 위임한다라..

우리는 이벤트를 다룰 때 비슷한 방식으로 여러 요소에 다뤄야 할 경우가 생긴다.
이럴 때 각 요소마다 핸들러를 할당하는 귀찮은 과정을 거치지 않고

이벤트의 흐름을 이용하여 공통 조상에 이벤트 핸들러를 오직 하나만 할당해도 여러 요소를 한꺼번에 다룰 수 있다!

즉, 이벤트 리스너가 실행할 작업을 요소의 부모 요소에게 위임(Delegation)할 수 있다.
귀차니즘이 심한 나에게 단비같은 이벤트 위임이다.

아래 코드를 확인해 보자.

<h1> TODOS </h1>
<input id="new-todo-title" class="new-todo" placeholder="할일을 추가해주세요" autofocus />
<ul class="todoList">
	<li>
		<input type="checkbox" id="todo1">
		<label for="todo1"> 운동하기 </label>
	</li>
	<li>
		<input type="checkbox" id="todo2">
		<label for="todo2"> 강의듣기 </label>
	</li>
</ul>
var lists = document.querySelectorAll('li');
lists.forEach(function(li) {
  li.addEventListener('click', onClick);
});

js의 querySelectorAll 을 이용해 모든 li에 이벤트 리스커를 추가하는 코드이다.
코드를 실행해보면 잘 작동하는 것을 볼 수 있다.
하지만
만약 새로운 할일을 입력해서 li를 계속 추가해나간다면?
새로 추가된 li에는 js 파일에서 작성한 event가 등록되어 있지 않기 때문에
click 이벤트는 발생하지 않는다.

🚨도와줘요 이벤트 위임!!!!

사실 이 문제는 이벤트 위임을 사용하면 간단하게 해결이 된다.

var todoList = document.querySelector('.todoList');
todoList.addEventListener('click', onClick);

위의 코드처럼
li에 일일이 이벤트 리스너를 추가하는 대신
상위 요소인 ul 태그에 이벤트 리스너를 달아놓고 하위에 발생한 click event를 감지한다.
이것을 이벤트 버블링 이라고 한다.

이벤트 버블링?

이벤트 위임에는 버블링캡쳐 두가지가 있다.
오늘은 이벤트 버블링에 대해 살펴보겠다.

아래 코드를 확인해보자.

<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 태크 <div class="three"></div> 를 클릭하면
three
two
one

이 차례대로 실행된다.

왜!! 도대체 왜? 나는 three만 눌렀는데?

이 문제의 해답은 브라우저가 이벤트를 감지하는 방식에서 찾을 수 있다.

브라우저는 특정 화면 요소에서 이벤트가 발생하면 그 이벤트를 최상위에 있는 화면 요소까지 전파시킨다. 따라서 three-> two -> one 순서로 이벤트가 실행된다.

여기서 주의할 점은 각 태그마다 이벤트가 등록되어 있기 때문에 상위 요소로 이벤트가 전달된다는 것이다.
먄약 one div 태그에만 이벤트가 등록되어 있다면 위와 같은 결과는 나오지 않는다.

Reference

https://ko.javascript.info/event-delegation
https://joshua1988.github.io/web-development/javascript/event-propagation-delegation/#%EC%9D%B4%EB%B2%A4%ED%8A%B8-%EC%9C%84%EC%9E%84---event-delegation

profile
hello world!
post-custom-banner

0개의 댓글