JS / 동적 생성된 요소에 이벤트 핸들링

Duboo·2023년 8월 10일
0

브라우저 렌더링에 대해서 알고 있으면 쉽게 해결이 가능한 문제


Event handling

이벤트는 브라우저 혹은 운영체제 환경에 변경사항을 확인하는 브라우저 내부에서 발생하는 신호입니다.

웹 페이지 로딩부터 특정 요소 클릭, 키보드, 마우스, 브라우저 창의 크기, 비디오 그리고 에러까지 브라우저안에서 일어나는 거의 모든 이벤트를 확인할 수 있습니다.

개발자는 이러한 이벤트가 발생하면 실행되는 이벤트 핸들러 코드를 이용해서 적절한 응답을 할 수 있어야합니다.


addEventListener

이벤트 핸들링을 하는데 가장 권장되는 방법은 addEventListener 메서드 사용입니다.

const btn = document.querySelector("button");

function random(number) {
  return Math.floor(Math.random() * (number + 1));
}

btn.addEventListener("click", () => {
  const rndCol = `rgb(${random(255)}, ${random(255)}, ${random(255)})`;
  document.body.style.backgroundColor = rndCol;
});

addEventListener 메서드는 단순한 click 뿐만 아니라 load, upload, scroll, keydown, mouseup 등.... 브라우저 화면안에서 일어나는 거의 모든 이벤트를 확인할 수 있습니다.

또한 이벤트 핸들러를 제한없이 등록할 수 있고 이벤트를 발생시키는 리스너가 명확합니다.

이는 개발자 입장에서 가독성과 효율성을 챙길 수 있는 매우 좋은 방법입니다.

한가지 더 중요한 부분은 Can I use?에서 확인할 수 있습니다.

이제는 익스플로러가 사용이 중단되고 브라우저별로 대부분 다 사용할 수 있다고는 하지만 브라우저별 호환성 체크에도 유리합니다.


이벤트를 등록하는 다른 방법들

// onevent
const btn = document.querySelector("button");

function greet(event) {
  console.log("greet:", event);
}

btn.onclick = greet;

위의 이벤트 처리 말고 다른 방법들은 보통onevent을 사용해 요소(태그)안에 직접 이벤트 핸들러 처리를 하게됩니다.

특별한 경우가 아닌 이상 버그가 생기거나 문제가 생기진 않겠지만 html은 말그대로 마크업 언어이기 때문에 뼈대를 만드는데 집중하는게 가독성과 효율성에서 더 많은 이점을 가져올 수 있기에 권장되는 방법은 아닙니다.

// onevent 코드처럼 스크립트안으로 들어와 이벤트 처리를 할 수 있지만 해당 방법으로는 이벤트를 하나만 처리할 수 있는 단점이 있습니다.

let h = document.getElementById('a');
h.onclick = doThing_1;
h.onclick = doThing_2;

h.addEventListener('click', doThing_3);
h.addEventListener('click', doThing_4);

위 코드가 2, 3, 4는 동작하지만 1은 동작하지 않는 이유입니다.


동적으로 생성된 요소에 이벤트 핸들링

여기서 생기는 문제는 브라우저가 렌더링이 완료된 후 시점에는 동적으로 생성된 요소를 찾을 수 없기 때문에 이벤트 핸들링을 할 수 없습니다.

해결하는 방법은 브라우저의 렌더링 원리만 알아도 간단하게 해결이 가능합니다.

이미 렌더링이 끝난 DOM안에 내가 찾는 요소가 없기 때문에 이벤트 바인딩을 할 수 없을텐데 브라우저에게 동적으로 생성된 요소를 다시 한번 찾아봐라고 할 수 있으면 내가 원하는 요소를 찾을 수 있습니다.

모든 DOM 요소를 찾아보는 것보다 더 효율적인 방법은 내가 동적으로 생성된 DOM요소에 가장 가까운 요소를 확인하면 됩니다.

// 정적으로 생성된 부모 요소
const parent = document.querySelector('.parent');

// 동적으로 생성된 자식 요소
const btn = document.getElementById('btn');

parent.addEventListener(('event'), (e) => {e.currentTarget.children[0].doSomeTing...})

위 코드처럼 부모 요소를 이용하는 방법인데 부모 요소는 이미 정적으로 생성된 상태이기 때문에 해당 부모를 이용해 이벤트 바인딩을 만들어 자식 요소를 다시 한번 확인하게 만들면 됩니다.

profile
둡둡

0개의 댓글