이벤트 버블링과 이벤트 캡쳐, 이제는 내 것으로 만들자(자바스크립트)

이벤트버블링과 이벤트캡쳐, 개념과 활용

1. 이벤트 버블링

(이벤트 버블링은 거품이 퐁퐁퐁퐁 일어나듯이 이벤트가 퐁퐁퐁퐁 일어나 ‘버블링(Bubbling)’이라는 이름을 갖게 되었다는 글을 어디선가 본 적이 있습니다..)

이벤트 버블링은 이벤트 발생 요소에서부터 순서대로 최상위 부모 요소까지 퐁퐁퐁퐁 이벤트가 연달아 발생합니다.

동작을 확인하기 위해 다음 코드의 결과를 보겠습니다.

<style>
  .upper{
    background:gold;
    width:70px;
    text-align:center;
  } 
  .middle{
    background:orange;
    width:50px;
    text-align:center;
  }
  .lower{
    background:pink;
    width:30px;
  }
</style>

<script>
  function clicked(event){
    alert(event.currentTarget.getAttribute('id'));
  }
</script>

<div class="upper" onClick="clicked(event)" id="쌉">a
  <div class="middle" onClick="clicked(event)" id="가">b
    <div class="lower" onClick="clicked(event)" id="능">c
    </div>
  </div>
  
</div>

위 코드를 실행하면 다음 그림과 같은 결과가 나옵니다.

여기서 가장 내부에 자리 잡고 있는 c를 클릭하면 어떤 순서대로 이벤트가 실행될까요?

이벤트 버블링이 default로 설정되어 있으므로 c, b, a의 순서대로 이벤트가 발생합니다.

그러므로 위 코드라면 ‘능’ -> ‘가’ -> ‘쌉’ 의 순서대로 알림창이 뜹니다.

b를 클릭하면 ‘가’ -> ‘쌉’ 의 순서로 알림창이 뜹니다.

그렇다면 순서를 ‘쌉’ -> ‘가’ -> ‘능’ 으로 만들려면 어떻게 해야 할까요? 바로 이벤트 캡쳐를 사용하면 됩니다.

2. 이벤트 캡쳐

이벤트 캡쳐를 사용하려면 addEventListener 내부에 capture 값을 명시적으로 true로 변경해줘야 합니다.

기본값은 false이며, false는 이벤트 버블링, true는 이벤트 캡쳐를 의미합니다.

function clicked(event){
    alert(event.currentTarget.getAttribute('id'));
}

const divs = document.querySelectorAll('div');
divs.forEach(function(div) {
	div.addEventListener('click', clicked,{
  	capture:true
  }
  );
});  

<div class="upper" id="쌉">a
  <div class="middle" id="가">b
    <div class="lower" id="능">c
    </div>
  </div>
</div>

위 코드에서 capture:true로 설정해주고 다시 c를 클릭하면 이번에는 반대 순서인 위에서 아래로 이벤트가 발생합니다.

이제는 ‘쌉’ -> ‘가’ -> ‘능’ 의 순서로 알림이 뜹니다.

그렇다면 ‘이벤트 버블링도 싫고, 이벤트 캡쳐도 싫으니 둘 다 하지마!’라고 명령할 때는 어떻게 해야 할까요?

간단하게 이벤트와 함께 실행될 함수 내부에 event.stopPropagation()을 넣어주면 됩니다.

프로파간다(propaganda)를 닮은 그 단어 ‘propagation’은 ‘번식, 증식, 전파’등의 의미를 갖고 있습니다.

따라서 ‘이벤트의 증식 또는 전파를 멈추겠다’는 의미로 event.stopPropagation() 메소드를 사용하면 됩니다.

<style>
  .upper{
    background:gold;
    width:70px;
    text-align:center;
  } 
  .middle{
    background:orange;
    width:50px;
    text-align:center;
  }
  .lower{
    background:pink;
    width:30px;
  }
</style>

<script>
  function clicked(event){
    event.stopPropagation();
    alert(event.currentTarget.getAttribute('id'));
  }
</script>

<div class="upper" onClick="clicked(event)" id="쌉">a
  <div class="middle" onClick="clicked(event)" id="가">b
    <div class="lower" onClick="clicked(event)" id="능">c
    </div>
  </div>
  
</div>

위 메서드는 더 이상 ‘쌉 가 능’ 또는 ‘능 가 쌉’ 따위의 단어를 완성하도록 내버려두지 않습니다.

c를 눌러도 ‘쌉’ 또는 ‘능’만 띄울 뿐입니다.



이벤트핸들링이벤트 캡쳐는 의도한 대로 이벤트를 발생시키기 위한 중요한 속성과 개념입니다.

위 개념은 다음 포스트와 관련이 있습니다.

target, currentTarget 차이가 뭘까?

백문불여일코드(code)이므로 코드를 통해 확인하고 연습하는 습관을 기르면 어제의 정보가 내일 나의 무기가 될 수 있을 것이라 생각합니다.

One thought on “이벤트 버블링과 이벤트 캡쳐, 이제는 내 것으로 만들자(자바스크립트)”

Comments are closed.