Skip to content

이벤트 리스너를 제거하는 방법

Published: at 오전 10:04

이벤트 리스너를 제대로 제거해 주지 않으면 메모리릭이 발생할 수 있다. 이벤트 리스너를 제거하는 방법을 알아보자.

목차

펼치기

이벤트 리스터를 추가하는 방법

이벤트 리스너를 추가하는 방법은 addEventListener를 사용하는 방법과 on을 사용하는 방법이 있다.

addEventListener를 사용하는 방법

window.addEventListener('scroll', () => {
  console.log('scroll');
});

on을 사용하는 방법

window.onscroll = () => {
  console.log('scroll');
};

차이점

addEventListener를 사용하는 방법은 여러개의 이벤트 리스너를 추가할 수 있고, removeEventListener를 사용하여 제거할 수 있다. on을 사용하는 방법은 하나의 이벤트 리스너만 추가할 수 있고, 제거할때는 null만 대입해 주면 손쉽게 제거할 수 있다.

이벤트 리스너를 제거하는 방법

기본적으로 동일한 콜백을 add할때와 remove할때 동일한 콜백을 넣어주어야 한다.

const scrollHandler = () => {
  console.log('scroll');
};

window.addEventListener('scroll', scrollHandler);

window.removeEventListener('scroll', scrollHandler);

유의점

만약 useCapturetrue로 설정하여 이벤트 리스너를 추가했다면, removeEventListener를 할때도 true로 설정하여 제거해주어야 한다. 그 외의 옵션같은 경우에도 브라우저마다 다르게 동작할 수 있으므로, 최대한 동일한 옵션을 넣어주는 것이 좋다.

AbortController를 사용하는 방법

const controller = new AbortController();
const signal = controller.signal;

window.addEventListener('scroll', () => {
  console.log('scroll');
}, { signal });

controller.abort();

abortController를 사용하면, 이벤트를 추가할때 signal을 옵션으로 넘겨주고, controller.abort()를 호출하면 이벤트 리스너가 제거된다.

cloneNode를 사용하는 방법

node를 클론하게 되면 addEvetnListener로 추가된 이벤트 리스너는 제거된 노드가 클론된다. 만약 이상태에서 기존의 노드를 replace하면, 이벤트 리스너가 제거된다.

Cloning a node copies all of its attributes and their values, including intrinsic (inline) listeners. It does not copy event listeners added using addEventListener() or those assigned to element properties (e.g., node.onclick = someFunction). Additionally, for a <canvas> element, the painted image is not copied.

const node = document.querySelector('.node');
const cloneNode = node.cloneNode(true);
const parent = node.parentNode;

parent.replaceChild(cloneNode, node);

등록된 이벤트 리스너 확인하는 법

크롬개발자 도구에서 등록된 이벤트 리스너 정보를 확인할 수 있다.

크롬 개발자 도구에서 이벤트 리스너 리스트

결론

이벤트 리스너를 등록하면 해당 스코프에 대한 참조가 생기기 때문에, 이벤트 리스너를 제거하지 않으면 메모리 릭이 발생할 수 있다. 리액트나, 뷰 같은 프레임워크를 사용한다면 주로 onClick이나 @click를 통해 이벤트를 등록하겠지만, useEffectonMounted 통해 window나 document처럼 전역객체에 이벤트를 등록했다면, return문이나 onUnmounted를 통해 이벤트 리스너를 제거하는 것을 잊지 말자.