[javascript] 브라우저 이벤트 위임

sangyong park·2023년 2월 24일
0
post-custom-banner

이벤트 위임

캡처링과 버블링을 활용하면 이벤트 핸들링 패턴인 이벤트 위임을 구현할 수 있다.

이벤트 위임은 비슷한 방식으로 여러 요소를 다뤄야 할 때 사용된다. 이벤트 위임을 사용하면 요소마다 핸들러를 할당하지 않고, 요소의 공통 조상에 이벤트 핸들러를 단 하나만 할당해도 여러 요소를 한꺼번에 다룰 수 있다.

공통 조상에 할당한 핸들러에서 event.target을 이용하면 실제 어디서 이벤트가 발생했는지 알 수 있다.

<table>
  <tr>
    <th colspan="3"><em>Bagua</em> Chart: Direction, Element, Color, Meaning</th>
  </tr>
  <tr>
    <td class="nw"><strong>Northwest</strong><br>Metal<br>Silver<br>Elders</td>
    <td class="n">...</td>
    <td class="ne">...</td>
  </tr>
  <tr>...2 more lines of this kind...</tr>
  <tr>...2 more lines of this kind...</tr>
</table>

지금 해야 할 작업은 <td>를 클릭했을 때, 그 칸을 강조하는 것

<td>마다 onclick 핸들러를 할당하는 대신, '모든 이벤트를 잡아내는' 핸들러를 <table> 요소에 할당한다.

<table> 요소에 할당하게 될 핸들러는 event.target을 이용해 어떤 요소가 클릭 되었는지 감지하고, 해당 칸을 강조하게 된다.

<script>
let selectedTd;

table.onclick = function(event) {
  let target = event.target; // 클릭이 어디서 발생했을까요?

  if (target.tagName != 'TD') return; // TD에서 발생한 게 아니라면 아무 작업도 하지 않습니다,

  highlight(target); // 강조 함
};

function highlight(td) {
  if (selectedTd) { // 이미 강조되어있는 칸이 있다면 원상태로 바꿔줌
    selectedTd.classList.remove('highlight');
  }
  selectedTd = td;
  selectedTd.classList.add('highlight'); // 새로운 td를 강조 함
}
</script>

이벤트 위임 활용하기

'저장하기', '불러오기', '검색하기'등의 버튼이 있는 메뉴를 구현해야 한다고 가정해보자. 각 버튼의 기능과 관련된 메서드 save, load, search가 있는 객체도 이미 구현한 상태이다.

메뉴 전체에 핸들러를 하나 추가해주고, 각 버튼의 data-action 속성에 호출할 메서드를 할당해 주는 방법이다.

<button data-action="save">저장하기</button>

핸들러는 속성값을 읽고 적절한 메서드를 실행한다.

<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에 그 메서드를 써주기만 하면 된다.
  • 언제든지 버튼을 추가하고 제거할 수 있어 HTML 구조가 유연해진다.

.action-save, .action-load 같은 클래스를 사용할 수도 있지만, data-action 속성이 좀 더 의미론적으로 낫고 CSS 규칙을 적용할 수도 있게 된다.

profile
Dreams don't run away It is always myself who runs away.
post-custom-banner

0개의 댓글