Skip to main content

addEventListener and removeEventListener

addEventListener() registers a handler function that the browser calls when a given event happens on an element, and removeEventListener() unregisters a handler that was added earlier. Both methods are available on any DOM node, as well as on window and document.

Theory

TL;DR

  • addEventListener(type, listener, options) subscribes a function to an event.
  • Any number of listeners can be attached to the same event.
  • The handler receives an event object with data about the event: type, target and more.
  • removeEventListener(type, listener, options) cancels the subscription.
  • Only the exact function that was added can be removed: a fresh anonymous arrow will not match.
  • The { once, capture, passive } options control how the listener behaves.

Quick example

html
<button id="btn">Click me</button>
javascript
const btn = document.querySelector('#btn'); function handleClick() { alert('Button clicked!'); } btn.addEventListener('click', handleClick); // later, when the reaction is no longer needed btn.removeEventListener('click', handleClick);

The addEventListener signature

javascript
element.addEventListener(type, listener, options);
ArgumentWhat it means
typea string, the event name ('click', 'input', 'keydown' and so on)
listenerthe function that runs when the event fires
options (optional)an object with extra settings, for example { once: true }

Once subscribed, the handler is called every time the event reaches that element. The main advantage over the old onclick property is that there can be many listeners and they do not overwrite each other.

The event object

The browser passes the handler an event object carrying all the information about what happened:

javascript
btn.addEventListener('click', (event) => { console.log(event.type); // "click" console.log(event.target); // the element that was clicked });

Listener options

javascript
btn.addEventListener('click', handler, { once: true, // the handler runs only once capture: false, // listen on the bubbling phase, this is the default passive: true, // tells the browser that preventDefault will not be called });

once: true detaches the listener automatically after the first run, so a separate removeEventListener call is no longer needed. passive: true lets the browser scroll without waiting for the handler, which noticeably improves smoothness on touch screens.

Removing a handler: the same function

javascript
element.removeEventListener(type, listener, options);

Important: to remove a handler you have to pass the very same function you passed to addEventListener.

Wrong:

javascript
btn.addEventListener('click', () => console.log('hi')); btn.removeEventListener('click', () => console.log('hi')); // will not work

Here two different anonymous functions are created, and the browser has no idea which one to drop.

Right:

javascript
function handleClick() { console.log('hi'); } btn.addEventListener('click', handleClick); btn.removeEventListener('click', handleClick);

Now the removal works.

A practical example and summary

javascript
function handleScroll() { console.log('Scrolling!'); } // start listening window.addEventListener('scroll', handleScroll); // stop listening after 3 seconds setTimeout(() => { window.removeEventListener('scroll', handleScroll); console.log('Listener removed!'); }, 3000);
MethodWhat it doesNotes
addEventListener()adds an event handlerseveral listeners can be attached to one event
removeEventListener()removes a handlerworks only with the same function object
optionssettings{ once, capture, passive } control the listener's behaviour

Common mistakes

  • Passing a new anonymous function, or a new .bind(this) result, to removeEventListener: the reference differs, so the listener stays attached.
  • Forgetting that capture must match: a listener added with { capture: true } is only removed with the same capture value.
  • Not detaching listeners from window or document when a component is destroyed, which causes memory leaks.
  • Calling preventDefault() inside a passive: true listener: the browser ignores it and logs a warning.
  • Attaching addEventListener on every re-render and piling up duplicate handlers.

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.