이벤트 전파

1TBhard·2023년 1월 7일
0

FrontEnd면접

목록 보기
6/7
post-thumbnail

📌 "이벤트 버블링(Event Bubbling)과 이벤트 캡쳐링(Event Capturing), 이벤트 위임(Event Delegation)에 대해서 설명하세요."

DOM의 이벤트 전파 방식

DOM 이벤트는 아래와 같이 이벤트의 전파가 이루어진다.

  1. 이벤트 캡처링(Capture Phase) - 이벤트가 아래로 전파
  2. Target Phase - 이벤트가 Target element에 도달
  3. 이벤트 버블링(Bubbling Phase) - 이벤트가 위로 전파

event-propagation


이벤트 캡처링?

이벤트 캡처링(Event Capturing) 이란 이벤트 버블링과 반대로 상위에서 하위로 이벤트가 전달되는 것을 말한다.

  • DOM 트리 를 통해 이벤트를 전파한다.
    • 이벤트는 이벤트가 실행된 엘리먼트부터 맨 위(window)까지 전파된다.
    • 그리고 이벤트 리스너에 의해 이벤트가 catch 되어 해당 콜백을 실행할지가 결정된다.
  • .addEventListener() 에서 세번째 인자로 true 혹은 {capture: true} 을 전달해야한다.
    • .addEventListener(event, callback, true)
    • .addEventListener(event, callback, { capture: true } )
  • {cpature: true} 라면 Cpaturing Phase후 TargetPhase 에 도착하면 다음 이벤트 진행은 종료된다.

예제는 아래와 같다.

<body>
  <div class="one">
    <div class="two">
      <div class="three">
      </div>
    </div>
  </div>
  
  <script>
    const divs = document.querySelectorAll("div");

    function logText(e) {
	    console.log(this.classList.value);
    }

    // 이벤트 등록
    divs.forEach((div) =>
	    div.addEventListener("click", logText, {
  		  // 이벤트 캡쳐 활성화
  		  capture: true,
	    })
    );
  </script>
</body>

event-capturing


이벤트 버블링?

이벤트 버블링(Event Bubbling)이란 해당 엘리먼트가 상위의 엘리먼트로 이벤트가 전달되는 특성이다.

  • DOM 트리 를 통해 이벤트를 전파한다.
    • 이벤트는 이벤트가 실행된 엘리먼트부터 맨 하위 차일드까지 전파된다.
    • 그리고 이벤트 리스너에 의해 이벤트가 catch 되어 해당 콜백을 실행할지가 결정된다.
  • 브라우저는 기본으로 이벤트 버블링을 진행한다.
    • .addEventListener(event, callback, { capture: false })

⚠️ 아래 이벤트들은 버블링되지 않는다.

focus, blur, load, unload, change, reset, scroll, 대부분 DOM 이벤트

<body>
  <div class="one">
    <div class="two">
      <div class="three">
      </div>
    </div>
  </div>

  <script>
    const divs = document.querySelectorAll('div');

    function logText(e) {
      console.log(this.classList.value);
    }

    // 모든 div에 대해 이벤트 등록
    divs.forEach(div => div.addEventListener('click', logText));
  </script>
</body>

이벤트-버블링

이벤트 버블링과 캡처링은 결국 자신이 아닌 요소까지도 이벤트를 전달하게 된다.
이를 이용하여 이벤트 위임이라는 것을 이용할 수 있다.


이벤트 위임

이벤트 위임(Event Delegation)이란 하위 요소에 각각 이벤트를 붙이지 않고 상위 요소에서 하위 요소의 이벤트들을 제어하는 방식이다.

  • 클릭한 지점이 하위 엘리먼트라 해도, 그것을 감싸는 상위 엘리먼트까지 올라가면서 이벤트 리스너를 찾게 된다.
  • 자식으로 부터 이벤트를 전파(이벤트 버블링)한다.
  • 같은 레벨의 노드는 서로 이벤트 전파가 되지 않는다.

이에 대한 예제는 아래와 같다.


이벤트 위임시 유용한 것

Event.currentTarget

Event가 DOM을 통과할 때 이벤트의 현대 대상을 식별하려면 Event.currentTarget 을 사용한다.

const divs = document.querySelectorAll("div");
const button = document.querySelector("button");

function logText(e) {
	console.log(
		this.classList.value,
		e.currentTarget === e.target
	);
}

// 이벤트 등록
divs.forEach((div) => div.addEventListener("click", logText));

event-target

Event.stopPropagation()

이벤트의 추가 전파를 막는 메서드이다.
그러나 링크 클릭과 같은 기본적인 동작은 막지 않는다.
이를 막기 위해서는 Event.preventDefault() 혹은 Event.stopImmediatePropagation()
을 사용해야한다.

<body>
	<div class="one">
			1
			<!-- 이를 누를시 alert(two) 실행 후 naver.com 으로 이동 -->
			<a class="two" href="https://naver.com" onClick="twoFun()">
				2
				<!-- 이를 누를시 alert(three) 실행 후 이벤트 전파안되나, naver.com 으로 이동 -->
				<div class="three" onClick="threeFun(event)">3</div>
			</a>
		</div>

	<script>
		function twoFun() {
			alert("two");
		}

		function threeFun(event) {
			alert("three");
      		// event.preventDefault() 를 해줘야 페이지 이동하지 않음
			event.stopPropagation();
		}
	</script>
</body>

3을 클릭시 아래와 같이 three만 나오나 naver.com로 이동된다.

event-stopPropagation


참조

profile
기억을 넘어 습관으로

0개의 댓글