본문 바로가기

Javascript/이론+예제

이벤트 버블링, 이벤트 캡쳐링과 이벤트 위임

이벤트 버블링이란?

출처 : https://velog.io/@tlatjdgh3778/%EC%9D%B4%EB%B2%A4%ED%8A%B8-%EB%B2%84%EB%B8%94%EB%A7%81%EA%B3%BC-%EC%BA%A1%EC%B2%98%EB%A7%81%EC%97%90-%EB%8C%80%ED%95%9C-%EC%A0%95%EB%A6%AC

  • 특정 화면 요소에서 이벤트가 발생했을 때 해당 이벤트가 더 상위의 화면 요소들로 전달되어 가는 특성
  • 한 요소에 이벤트가 발생하면 이 요소에 할당된 핸들러가 동작 -> 부모 요소의 핸들러 동작 -> 최상단 부모 요소를 만날 때까지 반복되면서 핸들러가 동작하는 현상

 

이벤트 버블링을 막는 방법

  • event.stopPropagation() 사용
    • 이벤트의 전파를 원하지 않을 경우 사용하는 메소드
    • 이벤트 버블링이 되지 않길 바라는 타겟에게 이벤트 리스너를 줘서, 이 메소드를 사용하면 됨.
  • 예제
target.addEventListener("click", function(e){

  e.stopPropagation();

});

이벤트 캡쳐링이란?

출처 : https://velog.io/@tlatjdgh3778/%EC%9D%B4%EB%B2%A4%ED%8A%B8-%EB%B2%84%EB%B8%94%EB%A7%81%EA%B3%BC-%EC%BA%A1%EC%B2%98%EB%A7%81%EC%97%90-%EB%8C%80%ED%95%9C-%EC%A0%95%EB%A6%AC

  • 이벤트 버블링과 반대로, 브라우저로부터 이벤트가 발생한 요소까지 이벤트를 전달함.
  • Event Listener 의 옵션으로써 구현할 수 있음.

 

이벤트 캡쳐링 구현하는 방법

  • addEventListener 의 옵션을 설정해준다.
    • { capture : true }
    • true
이벤트를 등록할 때 아무런 옵션을 주지 않으면 버블링이 됨.
  • 예제
target.addEventListener("click", function(){}, true);

이벤트 위임 (event delegation)

: 캡처링과 버블링을 활용하면 강력한 이벤트 핸들링 패턴

  • 여러 요소들을 다뤄야할 때 사용됨
  • 하위 요소의 이벤트를 상위 요소에 위임함
  • 하위 요소의 이벤트를 상위에서 제어함
이벤트 위임의 장점

1. 많은 핸들러를 할당하지 않아도 되기 때문에, 초기화가 단순해지고 메모리 절약
2. 요소를 추가하거나 제거할 때 해당 요소에 할당된 핸들러를 추가하거나 제거 할 필요가 없기 때문에 코드가 간략해짐
3. innerHTML 이나 유사한 기능을 하는 스크립트로 요소 덩어리를 더하거나 뺄 수 있기 때문에 DOM 의 수정이 편리해짐

이벤트 위임의 단점

1. 이벤트 위임을 사용하려면 이벤트가 반드시 버블링 되어야함.
2. CPU 작업 부하 증가

 

이벤트 위임의 동작원리

  1. 컨테이너에 하나의 핸들러를 할당
  2. 핸들러의 event.target 을 사용해 이벤트가 발생한 요소가 어디인지 알아냄
  3. 원하는 요소에서 이벤트가 발생했다고 확인되면 이벤트를 핸들링한다.

 

이벤트 위임 활용하기

  • HTML 의 태그에 속성 부여해주기
    • ex ) data-action , data-val, data-code 등
    • .action-save , .action-load 같은 클래스를 사용할 수도 있지만, 
      data-action 속성이 좀 더 의미론적으로 낫습니다. CSS 규칙을 적용할 수도 있게 됩니다.
장점

1. 버튼 마다 핸들러를 할당해주는 코드를 작성할 필요가 없어짐
2. 언제든지 버튼을 추가하고 제거할 수 있어 HTML 구조가 유연해짐
<div id="menu">
  <button data-action="save">저장하기</button>
  <button data-action="load">불러오기</button>
  <button data-action="search">검색하기</button>
</div>

<script>
  class Menu {
    constructor(elem) {
      this._elem = elem;
      elem.onclick = this.onClick.bind(this); // (*)
    }

    save() {
      alert('저장하기');
    }

    load() {
      alert('불러오기');
    }

    search() {
      alert('검색하기');
    }

    onClick(event) {
      let action = event.target.dataset.action;
      if (action) {
        this[action]();
      }
    };
  }

  new Menu(menu);
</script>

 

  • 행동 패턴
    • 선언적 방식으로 "행동"을 추가할 때 사용
    • 특별한 속성과 클래스를 사용함
    • 구성
      • 요소의 행동을 설명하는 커스텀 속성을 HTML 속성에 추가함
      • 문서 전체를 감지하는 핸들러가 이벤트를 추척하게 함
장점

1. 새로운 행동을 선언해주는 속성을 추가해, 필요할 때마다 HTML 확장 가능
  • 예제 (카운터 구현)
첫 번째 카운터: <input type="button" value="1" data-counter>
두 번째 카운터: <input type="button" value="2" data-counter>

<script>
  document.addEventListener('click', function(event) {

    if (event.target.dataset.counter != undefined) { // 속성이 존재할 경우
      event.target.value++;
    }

  });
</script>

'Javascript > 이론+예제' 카테고리의 다른 글

Call , Apply, Bind  (0) 2022.12.30
this  (0) 2022.12.29
에러 핸들링(error handling)  (0) 2022.10.24
자바스크립트의 동작 원리  (2) 2022.10.22
API (Application Programming Interface)  (0) 2022.10.21