[javascript] 이벤트 위임

daewoong·2021년 9월 29일
0

이벤트 위임

사용자의 액션에 의해 이벤트 발생 시 이벤트는 document 레벨까지 버블링 되어 올라간다.(추후에 이벤트 버블링과 캡처링에 대해서 공부 후에 포스트할 예정이다.) 이 때문에 자식 엘리먼트에서 발생하는 이벤트를 부모 엘리먼트에서도 감지할 수 있다. 이러한 동작을 이용해 사용할 수 있는 방법이 이벤트 위임이다. 특정 엘리먼트에 하나하나 이벤트를 등록하지 않고 하나의 부모에 등록하여 부모에게 이벤트를 위임하는 방법이 바로 그것이다.

실습을 통해 확인해보자.
버튼을 통해 텍스트와 삭제버튼이 있는 엘리먼트를 추가하고 삭제버튼을 클릭하면 해당 엘리먼트를 삭제해보겠다.
우선 이벤트 위임을 사용하지 않고 작성해봤다.

<div>
  <button id="add-button">
    추가
  </button>
  <ul>

  </ul>
</div>
let num = 1;

const $addButton = document.querySelector("#add-button");
$addButton.addEventListener("click", () => {
  const $ul = document.querySelector("ul");
  $ul.insertAdjacentHTML('beforeend', `<li><span>요소${num++}</span><button class='remove-button'>삭제</button></li>`);
})

const $removeButton = document.querySelector(".remove-button");
$removeButton.addEventListener("click", (e) => {
  e.target.remove();
})

다음 코드를 https://jsfiddle.net/ 에서 확인해보면 놀랍게도 동작하지 않는다.

Uncaught TypeError: Cannot read properties of null (reading 'addEventListener')"

html에서 .remove-button 요소를 찾을수 없기 때문에 이벤트 리스너를 등록할 수 도 없다.

이벤트 위임을 사용해서 수정해보자

let num = 1;
const $addButton = document.querySelector("#add-button");
$addButton.addEventListener("click", () => {
	const $ul = document.querySelector("ul");
  $ul.insertAdjacentHTML('beforeend', `<li><span>요소${num++}</span><button class='remove-button'>삭제</button></li>`);
})

const $ul = document.querySelector("ul");
$ul.addEventListener("click", (e) => {
  if(e.target.classList.contains("remove-button")) {
    e.target.closest("li").remove();
  }
})

삭제 버튼의 상위 엘리먼트인 ul에 이벤트 리스너를 등록하여 클릭 이벤트가 실제로 발생한 곳이 삭제 버튼일 때 closest함수를 사용해 해당 삭제 버튼이 포함된 요소를 삭제하는 코드이다.

다음 코드를 https://jsfiddle.net/ 에서 확인해보면 잘 동작하는 것을 볼 수 있다.

결론

이벤트 위임을 사용해서 동적으로 추가되는 엘리먼트의 이벤트를 처리할 수 있다는 것을 확인했다. 그리고 다음과 같은 장점도 있다고 한다.

  1. 동적인 엘리먼트에 대한 이벤트 처리가 수월하다.
  2. 상위 엘리먼트에서만 이벤트 리스너를 관리하기 때문에 하위 엘리먼트는 자유롭게 추가 삭제할 수 있다.
  3. 이벤트 핸들러 관리가 쉽다.
  4. 동일한 이벤트에 대해 한 곳에서 관리하기 때문에 각각의 엘리먼트를 여러 곳에 등록하여 관리하는 것보다 관리가 수월하다.
  5. 메모리 사용량이 줄어든다.
  6. 동적으로 추가되는 이벤트가 없어지기 때문에 당연한 결과이다. 1000건의 각주를 등록한다고 생각해보면 고민할 필요로 없는 일이다.
  7. 메모리 누수 가능성도 줄어든다.
  8. 등록 핸들러 자체가 줄어들기 때문에 메모리 누수 가능성도 줄어든다.

참고 : https://ui.toast.com/weekly-pick/ko_20160826

profile
잘하자

0개의 댓글

Powered by GraphCDN, the GraphQL CDN