이벤트 버블링과 캡쳐링은 사실 이벤트 위임을 위한 선수 지식이라고 해도 과언이 아닌데,
이는 버블링과 캡쳐링을 활용하여 이벤트 위임을 구현할 수 있기 때문이다.
이벤트 위임은 "하위 요소에 각각의 이벤트를 붙이지 않고, 상위 요소에서만 이벤트를 등록하여 하위 요소의 이벤트들을 제어하는 방식"이다.
<!DOCTYPE html>
<html lang="ko-KR">
<head>
<meta charset="UTF-8"/>
<title>이벤트 위임</title>
</head>
<body>
<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>
<script>
var inputs = document.querySelectorAll('#item1, #item2');
inputs.forEach(function (input) {
input.addEventListener('click', function (event) {
console.log('클릭됨');
});
});
</script>
</body>
</html>
querySelectorAll()
를 이용하여 화면에 존재하는 모든 input의 체크박스 요소를 가져온 다음 각각의 input 요소에 클릭 이벤트를 추가한다.
각각의 ListItem의 체크박스를 한번씩 클릭할 때 마다 "클릭됨"이라는 출력 결과가 한번씩 출력이 된다.
<!DOCTYPE html>
<html lang="ko-KR">
<head>
<meta charset="UTF-8"/>
<title>이벤트 위임</title>
</head>
<body>
<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>
<li>
<input type="checkbox" id="item3">
<label for="item3">이벤트 위임 공부하기</label>
</li>
</ul>
<script>
var inputs = document.querySelectorAll('#item1, #item2');
inputs.forEach(function (input) {
input.addEventListener('click', function (event) {
console.log('클릭됨');
});
});
</script>
</body>
</html>
당연하게도 새로운 ListItem이 추가된 input의 item3 요소에는 querySelectorAll()
로 가져오지 않았기 때문에 클릭 이벤트가 선언되지 않았다고 말할 수 있다.
따라서, 클릭을 해도 "클릭됨"이라는 출력 결과가 나오지 않게 된다.
이렇게 매번 새롭게 추가되는 아이템 요소까지 클릭 이벤트를 일일이 달아줘야 할까?
<!DOCTYPE html>
<html lang="ko-KR">
<head>
<meta charset="UTF-8"/>
<title>이벤트 위임</title>
</head>
<body>
<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>
<li>
<input type="checkbox" id="item3">
<label for="item3">이벤트 위임 공부하기</label>
</li>
</ul>
<script>
var itemList = document.querySelector('.itemList');
itemList.addEventListener('click', function (event) {
console.log('클릭됨');
});
</script>
</body>
</html>
모든 input의 체크박스에 일일이 요소를 가져와서 EventListener를 추가하는 대신에 input과 li태그 상위 요소인 ul태그의 클래스로 .itemList
에 EventLisener를 달아놓고 클릭 이벤트만 설정해주면 위의 결과처럼 클릭할 때 마다 출력 결과가 정상적으로 나오게 된다.
장점 : 유지보수가 쉽고, 코드를 간결하게 만들어줄 수 있다.
단점 : 이벤트 버블링이 발생하는 경우에만 사용 가능하며, 상위 요소에 이벤트 핸들러를 등록하기 때문에 상세한 이벤트 동작을 파악하는데 가독성이 떨어질 수 있다.