본문 바로가기

Web/JavaScript

이벤트 위임(event delegation)

728x90

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

이를 이용해 이벤트를 핸들링한다

 

 

예시-> table 클릭했을때 "td" 엘리먼트에서 발생한 것만 작업하기

 

table.onclick = function(event) {
  let target = event.target; // 클릭한 타겟 찾기

  if (target.tagName != 'td') return; 
  doSomething(target); // td 엘리먼트에서 무언가를 실행
};

 

여기서 만약 td 의 자식에 이벤트가 있는지를 찾아해야한다

 

table.onclick = function(event) {
  let td = event.target.closest('td'); // (1)

  if (!td) return; // (2)

  if (!table.contains(td)) return; // (3)

  doSomething(td); // (4)
};
  1. elem.closest(selector) 메서드는 elem의 상위 요소 중 selector와 일치하는 가장 근접한 조상 요소를 반환. 위 코드에선 이벤트가 발생한 요소부터 시작해 위로 올라가며 가장 가까운 <td> 요소를 찾는다.
  2. event.target이 <td>안에 있지 않으면 그 즉시 null을 리턴.
  3. 중첩 테이블이 있는 경우 event.target은 현재 테이블 바깥에 있는 <td>가 될 수도 있다. 그렇기 때문에 클릭 시에 선언해둔 td가 해당 table 안에 있는지를 확인하고 포함되지않는다면 리턴.
  4. 무언가를 실행!

 

해당 클릭한 dataset 의 action 실행하기

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

 

 

토글

document.addEventListener('click', function(event) {
    let id = event.target.dataset.toggleId;
    if (!id) return;

    let elem = document.getElementById(id);

    elem.hidden = !elem.hidden;
  });

 

 

 

추가 해볼만한 것들

있던 엘리먼트를 새 엘리먼트로 감싸주기 (리스너 달때 유용할 듯)

for (let li of tree.querySelectorAll('li')) {
      let span = document.createElement('span');
      li.prepend(span);
      span.append(span.nextSibling); // 텍스트 노드를 span 안으로 옮깁니다.
    }

 

 

 

th에 정렬 달기

grid.onclick = function(e) {
      if (e.target.tagName != 'TH') return;

      let th = e.target;
      // 클릭한 요소가 TH라면 정렬을 진행합니다.
      // cellIndex는 몇 번째 열인지를 나타내는 인덱스 값입니다.
      //   첫 번째 열이라면 0,
      //   두 번째 열이라면 1이 됩니다.
      sortGrid(th.cellIndex, th.dataset.type);
    };

    function sortGrid(colNum, type) {
      let tbody = grid.querySelector('tbody');

      let rowsArray = Array.from(tbody.rows);

      // 변수 compare에 할당할 함수 compare(a, b)는 두 행을 비교하고 필요에 따라 정렬을 진행합니다.
      let compare;

      switch (type) {
        case 'number':
          compare = function(rowA, rowB) {
            return rowA.cells[colNum].innerHTML - rowB.cells[colNum].innerHTML;
          };
          break;
        case 'string':
          compare = function(rowA, rowB) {
            return rowA.cells[colNum].innerHTML > rowB.cells[colNum].innerHTML ? 1 : -1;
          };
          break;
      }

      // 해당 열을 정렬합니다.
      rowsArray.sort(compare);

      tbody.append(...rowsArray);
    }
728x90

'Web > JavaScript' 카테고리의 다른 글

브라우저 이벤트 정리 1. 마우스이벤트  (0) 2023.10.22
브라우저 기본 동작  (0) 2023.10.21
[Bubbling, Capturing]  (1) 2023.10.21
[browser event] 자주 이용하는 DOM 이벤트  (1) 2023.10.20
[ES6] promise, async 와 await  (1) 2023.10.19