[JavaScript] 이벤트 버블링

혜린·2022년 12월 8일
0

JavaScript

목록 보기
21/21
post-thumbnail

0. 이벤트 관련 용어 정리


이벤트 버블링에 대해 알기 이전에 용어를 정확히해두고 싶어
흔히 쓰이는 이벤트 리스너와 이벤트 핸들러가 진정 의미하는 것은 무엇인지 대해 알아보았다.

이벤트 리스너와 이벤트 핸들러를 합쳐 이벤트 리스너 혹은 이벤트 핸들러라고 한다.
하지만, 이를 정확하게 말하자면 이벤트 리스너에 등록된 콜백함수가 이벤트 핸들러이다.

div.onClick(() => {});
div.addEventListener('click', () => {});
이벤트이벤트 속성 (이벤트 리스너)이벤트 핸들러
clickaddEventListener(), onClick()function(){}



1. 이벤트 핸들러의 호출 과정


  1. ⬇ 하위 요소에 이벤트 전파 캡처링
  2. 💌 타깃 요소에 이벤트 전달
  3. ⬆ 상위 요소로 다시 이벤트 전파 버블링



2. 이벤트 버블링 (Event Bubbling)


🧼 이벤트 버블링이란?
특정 요소에서 이벤트가 발생됐을 때, 해당 이벤트가 상위 요소들로 전달되어 가는 특성을 말한다.


2-1. 예시

  • document객체를 만날 때까지, 각 요소에 할당된 onClick이 동작
  • 이벤트 핸들러의 동작 순서는 다음과 같다. p > div > form


2-2. 왜 이벤트 버블링인가?

이벤트가 제일 깊은 곳의 요소에서부터 시작해 부모 요소를 거슬러 올라가며 이벤트가 발생하는 모양이 마치 물속 거품(bubble)과 같기 때문이다.


2-3. event.targetevent.currentTraget 의 차이점

타깃(target) 요소

  • 이벤트가 발생한 가장 안쪽의 요소로, 내가 클릭한 바로 그 요소
  • event.target을 통해 접근 가능하다.
  • 버블링이 진행되어도 변하지 않는다.

event.currentTargetthis

  • event.currentTargetthis와 같다.
  • 왜냐? 메소드 내부의 this는 해당 메소드를 호출한 객체에 바인딩되기 때문이다.
  • 다음의 예시를 통해 확인해볼 수 있었다.
<!--HTML-->
<form>
      FORM
      <div>
        DIV
        <p>P</p>
      </div>
</form>
// JavaScript
function lalala(e) {
	console.dir(this); // div
  	console.log(e) // PointerEvent{}
    console.log(e.target); // <P>P</P>
    console.log(e.currentTarget); <div>...</div>
    console.log(e.currentTarget === this); true
      }
const divTest = document.querySelector("div");
divTest.addEventListener("click", lalala);


event.currentTarget

  • this, 즉 eventCurrentTarget은 현재 요소로, 현재 실행 중인 핸들러가 할당된 요소를 참조한다.
  • 아래의 이미지에서 form태그에만 onClick 핸들러가 있다고 했을 때, event.targetevent.currentTarget은 어떻게 다를까?
    • event.target : form 안쪽에 내가 실제 클릭한 요소
    • event.currentTarget : form 요소


2-4. 버블링 중단시키기

event.stopPropagation()
  • 이벤트 버블링을 막아야하는 경우는 거의 없다.
  • 위 메소드로 버블링을 막게되면, 사람들이 페이지의 어느 부분을 클릭했는지에 대한 분석 시스템이 동작하지 못하게 된다.

2-5. 주의

거의 대부분의 이벤트는 버블링되지만, 몇몇 버블링이되지 않는 이벤트도 있다.
(예) focus()



3. 이벤트 캡쳐 (Event Capture)


📸 이벤트 캡쳐란?

  • 이벤트 버블링과 반대되는 방법
  • 이벤트 핸들러 호출 과정의 캡처링 과정에서 이벤트를 잡아내는 방법


3-1. 이벤트 핸들러 동작 과정

form, div, p 태그에 모두 click 이벤트를 설정해놓았다고 했을 때, 어떤 순서로 동작하게 될까?

  1. p 클릭
  2. HTMLBODYFORMDIV 캡쳐링
  3. p 타깃요소에 이벤트 전달
  4. DIVFORMBODYHTML 버블링

3-2. capture 옵션

  • false : default 값으로, 이벤트 핸들러가 버블링 단계에서 동작한다.
  • true : 이벤트 핸들러가 캡처링 단계에서 동작한다.
div.addEventListener('click', () => {}, { capture: true }); // (1)
div.addEventListener('click', () => {}, true); // (2)

3-3. 버블링 vs. 캡쳐링

  • 캡쳐링 단계는 거의 쓰이지 않으며, 주로 버블링 단계의 이벤트만 다뤄진다.
  • 특정 요소를 클릭했을때 해당 내용에 대해서는 그 요소가 가장 잘 알고있기 때문에
  • 지역 사건이 일어났을 때 해당 지역의 담당이 먼저 처리해본뒤, 상위 기관으로 넘기는 것과 같은 원리이다.



4. 이벤트 위임 (Event Delegation)


🎁 이벤트 위임이란?

  • 이벤트 캡처링과 이벤트 버블링을 활용한 패턴
  • 하위 요소🧑🏻마다 이벤트를 등록하지 않고도
    하위 요소🧑🏻들의 공통된 부모 요소👵🏻에 이벤트를 등록하여
    하위 요소🧑🏻의 이벤트들을 관리하는 방식이다.

4-1. 예시

1. 이벤트 위임을 사용하지 않았을 때

<!--HTML-->
<ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
    <li>5</li>
    <li>6</li>
</ul>
// JavaScript
const li = document.querySelectorAll("li");

li.forEach((li) => {
	li.addEventListener("click", () => {
		li.classList.add("selected");
	});
});

2. 이벤트 위임을 사용했을 때

// JavaScript
const ul = document.querySelector("ul");

ul.addEventListener("click", (event) => {
	if (event.target.tagName == "LI") {
		event.target.classList.add("selected");
	}
});

4-2. 이벤트 위임을 사용하면 좋은점

여러 자식 요소에 모두 이벤트를 등록하는 것이 아닌,
부모 요소 하나에 등록함으로써 관리하기 때문에

  1. 이벤트 핸들러의 관리가 수월하다.
  2. 하위 요소를 자유롭게 추가하고 삭제할 수 있다.



정리


🧼 이벤트 버블링에 대해 설명해주세요!

  • 이벤트 버블링은 특정 요소에서 이벤트가 발생했을 때 해당 이벤트가 상위 요소들한테 차례로 전달되는 특성이다.
  • event.propagation() 메소드로 이러한 버블링 현상을 막을 수 있지만, 잘 사용되지 않는다.
  • 하위요소 → 상위요소로 이벤트가 전파되는 것은 이벤트 버블링이며, 이와 반대로 상위요소 → 하위요소로 이벤트가 전파되는 것은 이벤트 캡처링이다.
  • 이러한 이벤트 버블링, 캡쳐링 특성을 이용하여 하위요소마다 이벤트를 등록하지 않아도 공통된 상위요소에 이벤트를 등록해 관리할 수 있는 패턴을 이벤트 위임이라고 한다.



참고


이 글은 아래의 글을 바탕으로 공부하며 개인적으로 정리한 글입니다.
이미지에 대한 출처는 모두 아래에 있는 포스팅에 있습니다.

profile
FE Developer

0개의 댓글