이벤트 버블링이란 target에서 발생한 이벤트를 상위 요소로 전달하는 것입니다.
html
<body>
<div class="one">
<div class="two">
<div class="three">
</div>
</div>
</div>
</body>
javascript
const divs = document.querySelectorAll('div')
divs.forEach(function(div){
div.addEventListener('click', printLog)
});
function printLog(event){
console.log(event.currentTarget.className);
}
// 클래스명 three인 div를 클릭했을 때 결과
// three
// two
// one
// 클래스명 two인 div를 클릭했을 때 결과
// two
// one
결과에서 보는 것처럼 div 하나만 클릭해도 최상위 화면 요소까지 이벤트를 전파시킵니다.
이벤트 캡처링은 해당 이벤트가 발생한 요소의 최상위 요소에서 해당하는 태그를 찾아 내려가는 형태로 버블링과 반대 방향으로 동작합니다.
html
<body>
<div class="one">
<div class="two">
<div class="three">
</div>
</div>
</div>
</body>
javascript
const divs = document.querySelectorAll('div')
divs.forEach(function(div){
div.addEventListener('click', printLog), {
capture: true // default 값 === false
});
function printLog(event){
console.log(event.currentTarget.className);
}
// 클래스명 three인 div를 클릭했을 때 결과
// one
// two
// three
<div class="one"></div>
를 클릭해도 결과는 바뀌지 않습니다.
이벤트 위임이란 캡처링과 버블링을 활용한 이벤트 핸들링 패턴입니다. 요소마다 핸들러를 할당하지 않고, 요소의 공통 조상에 이벤트 핸들러를 하나만 할당하면 여러 요소를 한번에 다룰 수 있는 방법입니다.
공통 조상에 event.target
을 사용하면 이벤트 버블링으로 인해 어디서 이벤트가 발생했는지 알 수 있습니다. 이 점을 이용하여 이벤트를 핸들링합니다.
typescript
openDetailModal() {
const restaurantWrapper = $(".restaurant-wrapper") as HTMLDivElement;
restaurantWrapper.addEventListener("click", this.initDetailModal);
}
initDetailModal = (event: Event) => {
// find event.target & show detail modal using event.target's id
};
위의 코드는 제가 미션을 진행하며 사용한 코드인데요. restaurantWrapper가 감싸고 있는 restaurantList 내부의 restaurantItem를 클릭했을 때 발생할 이벤트를 restaurantItem에 개별적으로 add해준 것이 아니라 restaurantWrapper라는 상위 객체에 이벤트를 위임함으로써 리스트 아이템을 새로 추가할 때마다 클릭 이벤트를 달지 않아도 되도록 하였습니다😄 이벤트 위임을 사용하여 메모리 사용량도 감소되었다고 할 수 있겠습니다.