JS 이벤트 위임(event delegation)

이은지·2021년 12월 30일
1
post-custom-banner

브라우저가 이벤트를 감지하는 두 가지 방식 - 이벤트 버블링, 이벤트 캡처
이벤트 위임을 이해하기 위해 우선 이 두 가지부터 이해해보자.

🦄 이벤트 버블링(기본)

: 특정 화면 요소에서 이벤트가 발생했을 때 해당 이벤트가 더 상위의 화면 요소들로 전달되어 가는 방식

  • 한 요소에 이벤트 발생 ⇒ 이 요소에 해당된 핸들러가 동작 ⇒ 부모 요소의 핸들러가 동작
    최상위 요소를 만날 때까지 이 과정이 반복되며 요소 각각에 할당된 핸들러가 모두 동작
  • bottom-up 방식
  • 브라우저는 기본적으로 이벤트 버블링 방식을 취한다. 브라우저의 기본적인 이벤트 감지 방식이기 때문에 이해하고 있을 필요가 있다.

🦄 이벤트 캡쳐

: 특정 이벤트가 발생하면 최상위 요소인 body 태그에서 해당 태그를 찾아 내려가는 방식

  • addEventListener() 에 capture:true 를 설정해주면 이벤트 캡쳐 방식으로 바뀐다.
    돔요소.addEventListener('click', () => {}, {capture: true});

대부분 이벤트 버블링 방식을 사용한다.
특정 요소에 할당된 이벤트 핸들러는 그 요소에 대한 자세한 사항과 무슨 일을 해야 할 지 가장 잘 알고 있다.
따라서 해당 핸들러에게 그 요소를 다룰 기회를 가장 먼저 주는 것이라고 생각하면 된다.

🦋 이벤트 위임 Event Delegation

: 하위 요소가 여러 개 있을 때, 하위 요소에 각각 이벤트 핸들러를 달지 않고 상위 요소에만 이멘트 핸들러를 달아 하위 요소를 제어하는 방식. 일종의 코딩 패턴이라고 생각하면 된다.

이벤트 위임 방식으로 얻는 장점

  • 코드의 간결성 - 상위 요소에만 이벤트 핸들러를 추가하면 되므로
  • 메모리에 있게 되는 이벤트 핸들러가 적어지기 때문에 퍼포먼스 상의 이점이 존재
  • 동적으로 하위 요소를 추가할 때마다 이벤트 핸들러를 고려할 필요가 없음

이벤트 위임을 적용 하지 않은 코드 예시

// index.html

<h1>오늘의 할 일</h1>
<ul class="itemList">
	<li>
		<input type="checkbox" id="item1">
		<label for="item1">이벤트 버블링 학습</label>
	</li>
	<li>
		<input type="checkbox" id="item2">
		<label for="item2">이벤트 캡쳐 학습</label>
	</li>
</ul>

// main.js

const inputs = document.querySelectorAll('input');
inputs.forEach(function(input) {
	input.addEventListener('click', function(event) { // 모든 input태그에 이벤트 리스너를 추가
		alert('clicked');
	});
});

이벤트 위임을 적용한 예시

var itemList = document.querySelector('.itemList');
itemList.addEventListener('click', function(event) {
	alert('clicked');
});

// input태그의 상위 태그인 ul태그에만 이벤트 리스너를 추가
// 하위 요소에 이벤트가 발생하면 alert창이 뜬다.

하위 요소인 input태그에는 이벤트 핸들러가 없으므로 input태그에서 이벤트 발생 시 상위 요소인 ul태그의 이벤트 핸들러만 작동함! (이벤트 버블링 방식)

기본적으로 이벤트 버블링 방식임은 동일하나 상위 요소에만 이벤트 핸들러를 추가함으로써 상위 요소에서 하위 요소의 이벤트를 관리할 수 있게 함

🦋 event.target / event.currentTarget 의 차이점

event.target : 이벤트가 발생한 가장 하위 요소

event.currentTarget : 이벤트를 핸들링하는 현재 요소 ( = this)

A요소에서 이벤트 발생 ⇒ A가 event.target 이자 event.currentTarget 이 된다.

A요소 이벤트 핸들러 실행 후 A.parent 의 이벤트 핸들러 실행 ⇒ A.parent 가 event.currentTarget 이 된다.


+) 이벤트 전달이 아예 발생하지 않게 하고 싶다면 event.stopPropagation()
그러나 함부로 설정하는 것은 추천하지는 않는다고.

References
버블링과 캡처링
이벤트 버블링, 이벤트 캡처 그리고 이벤트 위임까지

post-custom-banner

0개의 댓글