브라우저가 이벤트를 감지하는 두 가지 방식 - 이벤트 버블링, 이벤트 캡처
이벤트 위임을 이해하기 위해 우선 이 두 가지부터 이해해보자.
: 특정 화면 요소에서 이벤트가 발생했을 때 해당 이벤트가 더 상위의 화면 요소들로 전달되어 가는 방식
: 특정 이벤트가 발생하면 최상위 요소인 body 태그에서 해당 태그를 찾아 내려가는 방식
돔요소.addEventListener('click', () => {}, {capture: true});
대부분 이벤트 버블링 방식을 사용한다.
특정 요소에 할당된 이벤트 핸들러는 그 요소에 대한 자세한 사항과 무슨 일을 해야 할 지 가장 잘 알고 있다.
따라서 해당 핸들러에게 그 요소를 다룰 기회를 가장 먼저 주는 것이라고 생각하면 된다.
: 하위 요소가 여러 개 있을 때, 하위 요소에 각각 이벤트 핸들러를 달지 않고 상위 요소에만 이멘트 핸들러를 달아 하위 요소를 제어하는 방식. 일종의 코딩 패턴이라고 생각하면 된다.
이벤트 위임 방식으로 얻는 장점
이벤트 위임을 적용 하지 않은 코드 예시
// 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
: 이벤트를 핸들링하는 현재 요소 ( = this)
A요소에서 이벤트 발생 ⇒ A가 event.target
이자 event.currentTarget
이 된다.
A요소 이벤트 핸들러 실행 후 A.parent 의 이벤트 핸들러 실행 ⇒ A.parent 가 event.currentTarget
이 된다.
+) 이벤트 전달이 아예 발생하지 않게 하고 싶다면 event.stopPropagation()
그러나 함부로 설정하는 것은 추천하지는 않는다고.
References
버블링과 캡처링
이벤트 버블링, 이벤트 캡처 그리고 이벤트 위임까지