이벤트 위임 (Event Delegation)

ROCKBELL·2023년 6월 9일
0

자바스크립트

목록 보기
25/25

이벤트 위임이란?

이벤트 위임은 이벤트 리스너를 자식 요소 대신 부모 요소에 추가하는 기법

장점

부모 요소에 단일 핸들러만 필요하기 때문에 메모리 사용 공간 감소
요소의 추가 삭제시 별도로 이벤트를 바인딩하고 해제할 필요 없음

단점

이벤트 위임을 사용하기 위해서는 이벤트 버블링이 필요

사용 예시

  • 특정 요소 아래에 있는 여러 하위 요소를 비슷한 방식으로 다루는 경우
  • 사용자의 인터랙션을 통해 추가되는 아직 만들어지지 않은 요소에 이벤트 핸들러를 할당해야 하는 경우
<ul>
   <li>리스트 1</li>
   <li>리스트 2</li>
   <li>리스트 3</li>
</ul>
<button type="button">추가</button>
const list = document.querySelector("ul");
const listItems = document.querySelectorAll("li");

// before - 새로운 아이템에 대한 핸들러가 정상적으로 동작하지 않음
listItems.forEach((item) => {
   item.addEventListner("click", (event) => {
        console.log(e.target.innerText);
   });
})

// after - 새로운 아이템에도 이벤트 핸들러가 정상적으로 동작 
list.addEventListner("click", (event) => {
 if(e.target.tagName === "LI") {
 	console.log(e.target.innerText);
 }
});

document.querySelector("button").addEventListner("click", (event) => {
	const newItem = document.createElement("li");
  	newItem.innerText = "새 리스트";
    list.appendChild(newItem);
})

이벤트 버블링 (Event Bubbling)

특정 자식 요소에 이벤트가 발생하면 부모 요소에게까지 이벤트가 전달되는 현상

<div>
  div
   <p>
     p
     <span>span</span>
  </p>
</div>
const $span = document.querySelector("span");
const $p = document.querySelector("p");
const $div = document.querySelector("div");

const log = (message) => {
	console.log(message);	
}

$span.addEventListener("click", () => log("click span"));
$p.addEventListener("click", () => log("click p"));
$div.addEventListener("click", () => log("click div"));

<span>을 클릭하면 console.log 에 아래와 같이 자식 요소 이벤트 부터 부모 요소순으로 log 찍힘 (자식 -> 부모)

click span
click p
click div

이처럼 자식 요소 span 에서 이벤트가 발생하면 해당 이벤트가 부모 요소 p, div에 전달되는 현상을 이벤트 버블링이라고 한다

stopPropagation()

이벤트 버블링은 최종적으로 <html> 엘리먼트까지 전달되며, 이 이벤트를 막기 위해서는 event.stopPropagation() 을 추가하고, 여러 이벤트 핸들러가 있을 경우 event.stopImmediatePropagation() 을 사용하면 된다

  • event.stopPropagation() - 단일 이벤트 핸들러
  • event.stopImmediatedPropagation() - 복수 이벤트헨들러

이벤트 캡쳐링 (Event Capturing)

이벤트 캡쳐링은 특정 요소에서 이벤트가 발생 했을 경우, 이벤트의 최상단 부모 요소에서부터 전달되어 내려오는 현상

캡쳐링을 수행하기 위해서는 이벤트 핸들러에 { capture : true } 혹은 true 로 옵션 설정을 해야한다 ( default 는 false )

<div>
  div
   <p>
     p
     <span>span</span>
  </p>
</div>
const $span = document.querySelector("span");
const $p = document.querySelector("p");
const $div = document.querySelector("div");

const log = (message) => {
	console.log(message);	
}

$span.addEventListener("click", () => log("click span"), true);
$p.addEventListener("click", () => log("click p"), true);
$div.addEventListener("click", () => log("click div"), true);

<span>을 클릭하면 console.log 에 부모 요소의 이벤트 부터 자식 요소순으로 log가 찍힘 (부모 -> 자식)

click div
click p
click span

stopPropagation()

이벤트 캡쳐링에서도 stopPropagation() 을 통해 이벤트 전파를 막아줄 수 있으며, 이벤트 버블링에서는 target 요소만 이벤트를 발생하게해주는데 반해, 이벤트 캡처링에서는 최상위 부모 요소에게 이벤트가 발생하도록 해준다

  • 이벤트 버블링 - 타켓 요소
  • 이벤트 캡쳐링 - 최상위 부모 요소
profile
luv it

0개의 댓글