728x90

자바스크립트 이벤트 버블링과 캡쳐

자바스크립트

HTML DOM API에서 이벤트를 전파하는 방법에는 이벤트 캡쳐링과 이벤트 버블링이 있습니다. 이를 간단하게 소개해보겠습니다.

이벤트 캡쳐링

위 사진에서 Capture Phase (1)에 해당하는 부분이 이벤트 캡쳐링에 해당합니다. 이벤트가 가장 바깥쪽 요소부터 안쪽 요소로 즉, Target Phase (2)까지 전파가 됩니다.

<div id="parent">
  <div id="child">
    Click Me
  </div>
</div>
<script>
  const parent = document.querySelector('#parent');
  const child = document.querySelector('#child');

  parent.addEventListener('click', () => {
    alert('click parent div');
  }, true);
  child.addEventListener('click', () => {
    alert('click child div');
  });
</script>

위의 코드에서 'Click Me'를 감싸고 있는 DOM 엘리먼트를 클릭하면 'click parent div', 'click child div' 순서대로 2개의 Alert를 확인할 수 있습니다.

addEventListener의 useCapture 인자

이는 addEventListener의 3번째 인자 useCapturetrue로 설정했기 때문입니다. 3번째 인자를 options 객체로 넘길 수도 있는데, option 값은 다음과 같습니다.

{
  capture: boolean;
  once: boolean;
  passive: boolean;
}
  • capture: 값이 true 하면 이벤트 캡쳐링을 합니다.
  • once: 값이 true 라면 이벤트가 한 번만 발생됩니다.
  • passive: 값이 true 라면 콜백 함수 내부에 preventDefault()가 있다 하더라도 실행되지 않습니다.

이벤트 버블링

위 사진에서 Bubbling Phase (2)는 가장 안쪽 요소부터 바깥쪽 요소로 전파가 되는 것을 의미합니다.

웹 페이지 내의 한 엘리먼트가 감지되었을 때, 해당 엘리먼트의 계층 구조를 따라 올라가면서 Root Element까지 이벤트가 전달되는 것을 말합니다.

<div class="root" onclick="alert('3')">
  <div onclick="alert('2')">
    <div onclick="alert('1')">
      Click Me
      </div>
  </div>
</div>

위의 코드에서 'Click Me'를 감싸고 있는 DOM 엘리먼트를 클릭하면 1, 2, 3 순서대로 3개의 Alert를 확인할 수 있습니다.

하위 DOM Element부터 최종적으로 Document 객체까지 전달되는 특성을 이용해 상위 Element에서 이벤트 핸들러를 재정의해서 이벤트 전파를 제어할 수 있습니다.

'대부분'의 이벤트는 버블링 됩니다
모든 이벤트가 버블링 되는 것은 아닙니다. focus와 같이 버블링 되지 않는 몇몇 이벤트를 제외한 대부분의 이벤트는 버블링 됩니다.

event.target

부모 Element의 핸들러는 이벤트가 어디에서 발생했는지에 대해 알 수 있습니다. 이벤트가 발생한 Element는 target element라 불리고, event.target을 통해 접근할 수 있습니다.

event.target과 this(event.currentTarget)

event.targetthis(event.currentTarget)에는 다음과 같은 차이가 있습니다.

  • event.target은 실세 이벤트가 시작된 'target' element입니다. 이는 버블링이 진행되어서 부모의 이벤트가 실행되어도 변하지 않습니다.
  • this는 'current' element입니다. 현재 이벤트가 실행 중인 element를 참조합니다.

'이벤트 버블링' 섹션의 예제를 봤을 때, 가장 바깥쪽에 있는 div의 경우, 모든 child element의 이벤트에 의해 버블링 되어 실행됩니다. 가장 바깥쪽 div의 이벤트가 실행될 때 event.targetthis는 다음과 같습니다.

  • event,target: 이벤트가 처음 실행된 'Click Me' 텍스트를 감싸고 있는 div element
  • this: 현재 이벤트가 실행되고 있는 가장 바깥쪽 div element

버블링 중단

<div class="root" onclick="alert('3')">
  <div onclick="event.stopPropagation()">
    <div onclick="alert('1')">
      Click Me
      </div>
  </div>
</div>

위 코드는 'Click Me' 텍스트를 클릭하더라도 두 번째 div 이상으로 전파되지 않습니다. 이벤트가 발생한 Element의 상위 Element에서 onclick 이벤트를 작성할 때 event.stopPropagation() 함수를 이용해 이벤트 전파를 중단했기 때문입니다.

 

 

728x90
728x90