JS 공부 - 이벤트 전파와 위임

이윤표·2024년 3월 25일
0

이벤트 전파

이벤트 전파

  • DOM 요소 노드에서 발생한 이벤트는 DOM트리를 통해 전파된다.
  • 이벤트 전파는 이벤트 객체가 전파되는 방향에 따라 3단계로 구분한다.

💡 이벤트 전파 3단계

  • 캡처링 단계: 이벤트가 상위에서 하위 요소로 전파
  • 타깃 단계: 이벤트가 이벤트 타깃에 도달
  • 버블링 단계: 이벤트가 하위에서 상위 요소로 전파
    이벤트는 캡처링 - 타깃 - 버블링 순으로 전판한다.
<body>
	<ul id="fruits">
		<li id="apple">apple</li>
		<li id="banana">banana</li>
		<li id="kiwi">kiwi</li>
	</ul>
	<script>
		const $fruits = document.getElementById("fruits");
		const $banana = document.getElementById("banana");
		
		// ul태그 하위 요소인 li 요소를 클릭했을 때
		$fruits.addEventListener("click", e => {
	    	console.log(e.eventPhase); // 이벤트 단계 3 (버블링단계)
	    	console.log(e.target); // 이벤트 타깃 *[object HTMLLIElement]*
	    	console.log(e.currentTarget); // 커렌트 타깃 *[object HTMLULElement]*
		});
		
		$banana.addEventListener("click", e => {
	    	console.log(e.eventPhase); // 이벤트 단계 2 (타깃 단계)
	    	console.log(e.target); // 이벤트 타깃 *[object HTMLLIElement]*
	    	console.log(e.currentTarget); // 커렌트 타깃 *[object HTMLLIElement]*
		});
		
		$fruits.addEventListener("click", e => {
	    	console.log(e.eventPhase); // 이벤트 단계 1 (캡처링단계)
	    	console.log(e.target); // 이벤트 타깃 *[object HTMLLIElement]*
	    	console.log(e.currentTarget); // 커렌트 타깃 *[object HTMLULElement]*
		}, true);
	</script>
</body>

이와 같이 이벤트는 이벤트를 발생시킨 이벤트 타깃은 물론 상위 DOM요소에서도 캐치할 수 있다.

💡 event.target 와 event.currentTarget

  • event.target
    실제로 이벤트를 발생시킨 DOM 요소
  • event.currentTarget
    이벤트 핸들러가 바인딩된 DOM 요소
    EventTarget.addEventListener('eventType', functionName [, useCapture])
    addEventListener 방식으로 이벤트를 등록할 때 EventTarget 이 곧 event.currentTarget 이 된다.
  • event.targetevent.currentTarget 은 버블링/캡처링 과정에 따라 서로 다를 수 있다.

이벤트 캡처링 캐치 방법

  • 이벤트 핸들러 등록 방식 중 어트리뷰트/프로퍼티 방식은 타깃 단계와 버블링 단계만 캐치할 수 있다.
  • addEventListener 메서드 방식은 3번째 인자로 true 를 전달하면 캡처링 단계도 캐치할 수 있다. 3번째 인자로 false 를 전달하거나 생략하면 타깃 단계와 버블링 단계만 캐치할 수 있다.

이벤트 위임

function handleClick({ target }) {
    [...$fruits.children].forEach($fruit => {
	    // 로직 처리
    });
}

document.getElementById("apple").onclick = handleClick;
document.getElementById("banana").onclick = handleClick;
document.getElementById("kiwi").onclick = handleClick;

코드 문제 (위임 X)

  1. list가 많아진다면 그만큼 브라우저가 기억해야할 이벤트 리스너도 많아진다. (비효율)
  2. list가 동적으로 추가해야 할 때 추가로 이벤트를 등록해야한다.

function handleClick({ target }) {
		*// 이벤트를 발생시킨 요소가 #fruits > li 자식 요소가 아니면 무시*
		if (!target.matches('#fruits > li')) return;
    [...$fruits.children].forEach($fruit => {
	    // 로직 처리
    });
}
$fruits.onclick = handleClick;

이벤트 위임 효과

  • 브라우저가 너무 많은 이벤트 핸들러를 기억하지 않게 하고, DOM 이 추가/삭제 될때 Event등록을 매번 해줘야 하는 수고를 없앨 수 있다.

이벤트 전파 막기

  • stopPropagation 메서드 이용
  • 하위 DOM 요소의 이벤트를 개별적으로 처리하기 위해 이벤트 전파를 막는다.

참고

profile
프론트엔드 개발자 지망생

0개의 댓글