
addEventListener의 세 번째 인자인 Options 객체로 capture, once, passive 동작을 미세하게 조정할 수 있습니다.AbortController를 사용하면 여러 요소에 등록한 리스너를 signal 하나로 일괄 제거할 수 있습니다.자바스크립트는 기본적으로 이벤트 주도(Event-Driven) 방식으로 동작합니다. 브라우저 환경에서 사용자 클릭, 키보드 입력, 페이지 로드 등 다양한 사건(Event)에 반응해 로직을 실행하는 것이 핵심입니다.
보통은 다음과 같이 이벤트를 등록합니다.
button.addEventListener('click', () => { console.log('버튼 클릭됨!'); });
하지만 애플리케이션 규모가 커지면 이벤트를 다는 것만으로는 부족합니다. 메모리 누수(Memory Leak)를 방지하려면 이벤트를 적절히 제거해야 하고, 수많은 이벤트가 중첩된 복잡한 DOM 구조에서는 이벤트 전파(Propagation)를 정교하게 제어해야 하는 상황이 반드시 찾아옵니다.
이벤트 관리의 복잡성을 해결하려면 addEventListener의 세 번째 인자인 Options 객체와 AbortController를 활용합니다.
과거에는 removeEventListener를 위해 익명 함수 대신 기명 함수를 정의하고 따로 관리해야 하는 번거로움이 있었습니다. 현대적인 방식은 더 선언적이고 안전한 대안을 제공합니다.
이벤트를 깊이 있게 다루려면 DOM의 이벤트 전파 흐름을 먼저 이해해야 합니다.
addEventListener의 세 번째 인자로 객체를 넘겨 이벤트 동작을 미세하게 조정할 수 있습니다.
element.addEventListener('click', handler, { capture: true, // 캡처링 단계에서 이벤트 실행 once: true, // 딱 한 번만 실행하고 자동으로 제거 passive: true // scroll 성능 최적화 (preventDefault 호출 안 함을 명시) });
once: true: "모달 닫기"나 "최초 1회 실행"이 필요한 경우 유용합니다. 직접 제거하는 로직을 짤 필요가 없어 코드가 깔끔해집니다.passive: true: 스크롤(Scroll)이나 터치 이벤트에서 브라우저가 preventDefault() 호출을 기다리지 않게 하여 스크롤 성능을 개선합니다.여러 개의 이벤트를 한꺼번에 제거해야 할 때 기존 방식은 번거롭습니다. 이때 AbortController를 사용하면 전원을 끄듯 일괄 종료할 수 있습니다.
const controller = new AbortController(); const { signal } = controller; // 여러 요소에 동일한 signal 전달 window.addEventListener('resize', handleResize, { signal }); document.addEventListener('keydown', handleKey, { signal }); btn.addEventListener('click', handleClick, { signal }); // 원할 때 한 번에 모두 제거! controller.abort();
이 방식은 특히 React의 useEffect cleanup이나 SPA의 페이지 전환 시 등록된 모든 글로벌 이벤트를 한 번에 정리할 때 강력합니다.
passive 옵션으로 부드러운 스크롤 인터랙션을 제공합니다.once나 signal을 사용해 선언적으로 이벤트를 관리할 수 있습니다.signal 옵션 등은 구형 브라우저(IE 등)에서 지원되지 않으므로 폴리필이나 트랜스파일링 확인이 필요합니다.addEventListener는 가장 친숙하지만 그만큼 오용하기 쉬운 도구입니다. 캡처링·버블링의 원리를 정확히 이해하고 AbortController 같은 현대적인 관리 기법을 익히면 한 차원 높은 프론트엔드 아키텍처를 설계할 수 있습니다.
참고 자료: