Programming/Javascript

JavaScript 이벤트 전파 개념과 이벤트 전파 막는 방법

Jan92 2024. 4. 3. 23:55

JavaScript 이벤트 전파 개념 및 막는 방법 (click 이벤트 전파 문제)

javascript 이벤트 전파 막는 방법

<body>
  <div class="outer-div" onclick="click_outer_div(event)"> outer-div
    <div class="inner-div" onclick="click_inner_div(event)"> inner-div
    </div>
  </div>
</body>

<!-- javascript 영역 -->
<script>
  function click_outer_div(event) {
    console.log(event.currentTarget.className);
  }

  function click_inner_div(event) {
    console.log(event.currentTarget.className);
  }
</script>

 

다음 예시와 같이 'outer-div' 안에 'inner-div'라는 요소가 있고, 각 요소에 click 이벤트가 있는 상황에서 'inner-div'를 한 번 클릭하였을 때, 이미지 결과처럼 'click_inner_div' 함수 동작 후 'click_outer_div' 함수도 동작되는 상황을 발견하게 되었는데요.

 

관련된 내용을 찾아보니 JavaScript에서는 '이벤트 전파(Bubbling, Capturing)'라는 개념이 있었으며, 해당 개념 및 이벤트 전파를 막는 방법에 대해 정리하게 되었습니다.

 


Event 전파 (Capturing, Bubbling)

Event Capturing, Event Bubbling

javascript에서 이벤트 전파는 아래 세 가지 단계로 나뉘게 되는데요.

 

'Event Capturing, Event Bubbling'은 브라우저가 이벤트를 처리하는 과정 중에 발생하며, 이벤트의 처리를 유연하고 확장성 있게 또 효율성 있게 할 수 있도록 도와주는 메커니즘입니다.

 

 

1. Event Capturing

특정 요소에 대해 이벤트가 발생했을 때, 최상위 요소인 'document' 객체로부터 이벤트가 발생한 'event target' 요소에 도달할 때까지 이벤트가 하위로 전파됩니다.

 

2. Event Target

이벤트가 발생한 요소에서 이벤트 핸들러가 실행되는 단계입니다.

 

3. Event Bubbling

'Event Capturing'에서 이벤트가 하위로 전파되는 것과 반대로 이벤트가 상위로 전파됩니다.

특정 요소에 대해 이벤트가 발생했을 때, 최상위 요소인 'document' 객체에 도달할 때까지 이벤트가 상위로 전파됩니다.

 


전파를 막는 방법

'이벤트 캡쳐링'과 '이벤트 버블링'이 이벤트 처리의 유연성과 확장성을 제공하는 목적이지만, 전파되면 안 되는 부분에서 이벤트가 전파되는 것은 기능상의 문제가 될 수 있는데요.

 

아래 내용을 통해 javascript에서 이벤트 전파를 막는 몇 가지 방법과 세부적인 내용에 대해서 살펴보겠습니다.

 

 

1. event.stopPropagation()

event.stopPropagation()

<body>
  <div class="outer-div" onclick="click_outer_div(event)"> outer-div
    <div class="inner-div" onclick="click_inner_div(event)"> inner-div
    </div>
  </div>
</body>

<script>
  function click_outer_div(event) {
    console.log(event.currentTarget.className);
  }

  function click_inner_div(event) {
    console.log(event.currentTarget.className);
    event.stopPropagation();   //이벤트가 상위 DOM으로 전파되는 것을 막음
  }
</script>

 

'event.stopPropagation()' 함수는 이벤트가 상위 DOM으로 전파되지 않도록 하는 기능입니다.

 

기존에 'click_inner_div()' 함수 동작 후 이벤트 전파로 인해 'click_outer_div()' 함수가 동작했었지만, 'event.stopPropagation()'으로 인해 이벤트가 전파되지 않는 것을 확인할 수 있습니다.

 

 

 

2. event.stopImmediatePropagation()

 

'event.stopImmediatePropagation()' 함수 역시 이벤트가 상위 DOM으로 전파되지 않도록 하는 기능인데요.

 

앞선 'event.stopPropagation()' 함수와의 차이점은 'event.stopImmediatePropagation()' 함수의 경우 이벤트 대상 DOM에 여러 이벤트가 걸려 있을 때 해당 이벤트들 사이의 전파도 막아 준다는 것입니다.

 

* 하나의 DOM에 여러 이벤트가 걸리는 경우를 잘 보지는 못했지만, 그런 경우 상황에 맞게 'event.stopPropagation()' 또는 'event.stopImmediatePropagation()'을 활용해야 할 것 같습니다.

 

 

 

3. event.preventDefault()

event.preventDefault()

<body>
  <div class="outer-div" onclick="click_outer_div(event)"> outer-div
    <div class="inner-div" onclick="click_inner_div(event)"> inner-div
      <label for="id-checkbox">cb:</label>
      <input type="checkbox" id="id-checkbox" onclick="click_checkbox(event)"/>
    </div>
  </div>
</body>

<script>
  function click_outer_div(event) {
    console.log(event.currentTarget.className);
  }

  function click_inner_div(event) {
    console.log(event.currentTarget.className);
  }

  function click_checkbox(event) {
    console.log('clicked checkbox!');
    event.preventDefault();      // 이벤트의 기본 동작을 막음
  }
</script>

 

이어서 위의 두 가지 함수와 함께 소개되는 'event.preventDefault()' 함수입니다. 해당 함수는 현재 이벤트의 기본 동작을 중단하는 기능을 가지고 있는데요.

 

예시 이미지와 코드를 통해 'checkbox'를 클릭했을 때, 기본 동작인 체크는 되지 않고 이벤트 전파만 발생하는 결과를 확인할 수 있습니다.

이처럼 'event.preventDefault()' 함수는 현재 이벤트의 기본 동작을 중지시키는데요.

 

처음에는 단순하게 '기본 동작을 왜 중지시키는 거지?'라는 의문이 들었지만, 해당 기능은 클라이언트 측의 validation 검사 등에서 활용될 수 있습니다.

(조건이 만족하지 않을 때 체크박스가 클릭되지 않도록 한다거나, 키 입력에 대해 조건을 주어 특정 키가 입력되지 않게 하는 등)

 

* 해당 함수는 예시에서 본 것처럼 이벤트의 기본 동작만 막고 전파는 되기 때문에 이벤트의 기본 동작을 막으면서 전파까지 막기 위해서는 'event.preventDefault()' 함수와 함께 전파를 막는 함수도 추가로 사용해야 한다는 특징이 있습니다.

 

 

 

 

< 참고 자료 >

https://programmingsummaries.tistory.com/313
https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault