분류 javascript

기본으로 돌아 가기 : 이벤트 위임

컨텐츠 정보

  • 조회 262 (작성일 )

본문

Screenshot of the event delegation example code 


Back to basics는 프로젝트에서 계속 사용하는 기본적인 의존성 없는 웹 기술을 설명하는 일련의 작은 게시물입니다. 이것은 계시가 아니지만 수년에 걸쳐 견고하고 유지하기 쉬운 프로젝트를 구축하는 데 도움이 되었습니다.


웹 인터페이스를 구축 할 때 제가 가장 좋아하는 트릭 중 하나는 이벤트 위임입니다.


이벤트는 적용한 요소에서만 발생하는 것이 아닙니다. 대신 DOM 트리에서 이벤트까지 내려 갔다가 다시 백업됩니다. 이벤트 라이프 사이클의 이러한 단계를 이벤트 버블링 및 이벤트 캡처라고 합니다.


이것의 실질적인 결과는 문서의 모든 요소에 이벤트 핸들러를 적용 할 필요가 없다는 것입니다. 대신 종종 부모 요소에 대한 하나의 처리기로 충분합니다. 오래전에는 오래된 브라우저에서 이벤트 처리와 관련된 메모리 누수가 자주 발생했기 때문에 이것은 매우 중요했습니다.


링크 목록이 있고 이러한 링크를 따르는 대신 사용자가 클릭 할 때 코드에서 무언가를 수행하고 싶다고 가정 해 보겠습니다.

<ul id="dogs">
  <li><a href="#dog1">Dog1</a></li>
  <li><a href="#dog2">Dog2</a></li>
  <li><a href="#dog3">Dog3</a></li>
  <li><a href="#dog4">Dog4</a></li>
  <li><a href="#dog5">Dog5</a></li>
  <li><a href="#dog6">Dog6</a></li>
  <li><a href="#dog7">Dog7</a></li>
  <li><a href="#dog8">Dog8</a></li>
  <li><a href="#dog9">Dog9</a></li>
  <li><a href="#dog10">Dog10</a></li>
</ul>


각 링크를 반복하고 각각에 클릭 핸들러를 할당 할 수 있습니다.


const linkclicked = (e,l) => {
  console.log(l);
  output.innerHTML = l.innerHTML; 
  e.preventDefault();
};
const assignhandlers = elm => {
  let links = document.querySelectorAll(`${elm} a`);
  links.forEach(l => {
    l.addEventListener('click', e => {linkclicked(e,l)});
  });
}
assignhandlers('#dogs');


여기에서 이 이벤트 처리 예제를 시도 할 수 있으며 코드는 GitHub (event.handling.html)에서 사용할 수 있습니다.


작동하지만 두 가지 문제가 있습니다.


1. 목록의 내용이 변경되면 목록을 다시 색인화 해야 합니다 (에서와 같이 assignhandlers()를 한 번 더 호출).

2. 클릭 되는 링크에만 반응합니다. 목록 항목을 클릭 할 때도 무언가를 하려면 더 많은 핸들러를 할당해야 합니다.


예제에서 "Toggle more dogs"버튼을 클릭하여 이를 시도 할 수 있습니다. 목록에 더 많은 항목을 추가하고 항목을 클릭해도 아무 일도 일어나지 않습니다.


이벤트 위임을 사용하면 훨씬 쉽습니다.


document.querySelector('#dogs').
  addEventListener('click', e => {
    // What was clicked?
    let t = e.target; 
    // does it have an href?
    if (t.href) { 
      console.log(t.innerText); // f.e. "Dog5"  
      output.innerHTML = t.innerText; 
    }
    // if the list item was clicked
    if (t.nodeName === 'LI') { 
      // print out the link
      console.log(t.innerHTML);
      output.innerHTML = t.innerHTML; 
    }
  e.preventDefault(); // Don't follow the links
});


여기에서 이 이벤트 위임 예제를 시도해 볼 수 있으며 코드는 GitHub (event-delegation.html)에서 사용할 수 있습니다. 이제 "Toggle more dogs"버튼을 클릭하고 강아지가 있는 링크를 클릭하면 여전히 작동하는 것을 볼 수 있습니다.


클릭 이벤트가 발생한 요소를 확인하기 위해 수행 할 수 있는 몇 가지 작업이 있습니다. 여기서 가장 중요한 부분은 "let t = e.target;"입니다. 이벤트 캡처 / 버블링 주기에 의해 현재보고 되는 요소를 저장하는 행. 링크에 반응하고 싶다면 타겟에 "href"가 있는지 확인합니다. 목록 항목에 반응하고 싶다면 ‘nodeName’을 ‘LI’와 비교합니다. 이러한 종류의 검사를 수행하는 경우 노드 이름은 항상 대문자입니다.


더 많은 유연성을 제공하고 콘텐츠 변경에 대해 걱정할 필요가 없기 때문에 이벤트 위임을 정말 좋아합니다. 핸들러는 필요할 때까지 기다립니다.


https://christianheilmann.com/2020/11/01/back-to-basics-event-delegation/