이벤트 위임을 알기 위해선 선수지식으로 이벤트 버블링과 캡쳐링의 동작방식을 알아야 한다.
이벤트 버블링 이란, 하위 엘리먼트에 이벤트가 발생할 때 그 엘리먼트부터 시작해서 상위요소까지 이벤트가 전달되는 방식을 말한다.
이벤트 캡쳐링 이란, 하위 엘리먼트에 이벤트 핸들러가 있을 때 상위 엘리먼트부터 이벤트가 발생하기 시작해서 하위 엘리먼트까지 이벤트가 전달되는 방식을 말한다.
아래 예시를 보면 확실히 알 수 있다.
<div>
<ul>
<li>예시</li>
</ul>
</div>
document.querySelector('li').addEventListener('click', () => console.log('li 클릭'));
document.querySelector('ul').addEventListener('click', () => console.log('ul 클릭'));
document.querySelector('div').addEventListener('click', () => console.log('div 클릭'));
이렇게 각 엘리먼트들에 이벤트 핸들러를 달고 li
태그를 클릭해보면 콘솔에는 아래와 같이 찍히게 된다.
li 클릭
ul 클릭
div 클릭
즉, 기본적으로는 동작방식이 "이벤트 버블링" 인 것이다. 이 방식을 "이벤트 캡쳐링" 으로 바꾸기 위해선 addEventListener()
의 마지막 인자로 { capture: true }
를 전달해주면 된다. 이렇게 하면, 클릭한 엘리먼트의 상위요소 중 이벤트 캡쳐링이 적용된 엘리먼트부터 콘솔에 찍히고 그 다음부터는 다시 "이벤트 버블링" 방식을 동작한다. ul
의 이벤트 핸들러에 캡쳐링을 적용해보자.
document.querySelector('ul').addEventListener('click', () => console.log('ul 클릭'), { capture: true });
ul 클릭
li 클릭
div 클릭
li
부터는 다시 "이벤트 버블링" 이 동작해서 div
에 이벤트가 발생하는 것이다.
이벤트 위임 이란 하위 엘리먼트들이 여러개 있을 때, 하위 엘리먼트들에 각각 이벤트 핸들러를 달지 않고 상위 엘리먼트에 이벤트 핸들러를 달아 하위 엘리먼트들을 제어하는 방식이다. 이 패턴으로 얻는 이점들은 다음과 같다.
예시를 살펴보자.
<ul onclick="alert(event.type + '!')">
<li>첫번째</li>
<li>두번째</li>
<li>세번째</li>
</ul>
li
에 각각 핸들러를 달지 않고 상위 엘리먼트인 ul
에만 달았다는 걸 확인할 수 있다. 무조건 이벤트 위임이 좋은 것은 아니기 때문에 상황에 맞게 잘 사용하도록 하자.