addEventListener() in JavaScript: reacting to what the visitor does

addEventListener wires a function to an event: its once, passive and signal options, how to remove a listener, and why it beats onclick.
3 min read
Believemy logo

A page does nothing until somebody touches it. A click, a keystroke, a scroll: each of these gestures produces an event, sent by the browser to the element concerned.

What is still missing is a statement, made in advance, of what should happen next. That is the job of addEventListener.


Definition

addEventListener registers a function, called a listener, to run every time a given type of event reaches the element. It takes three arguments: the event name, the function, and an optional options object.

JAVASCRIPT
const button = document.querySelector("#confirm");

button.addEventListener("click", (event) => {
  console.log("click on", event.currentTarget.id);
  console.log("mouse button:", event.button);
});

The object handed over describes the event: the element aimed at, the moment, the keys held down. Its shape changes with the type, a KeyboardEvent carrying a key property that a MouseEvent does not have.


The options

OptionWhat it changes
onceThe listener runs a single time, then removes itself
captureThe listener fires on the way down, not on the way back up
passiveA promise never to cancel the default action, which smooths scrolling
signalAn AbortController signal that removes the listener once triggered
JAVASCRIPT
document.addEventListener("keydown", closeModal, { once: true });
zone.addEventListener("touchstart", followFinger, { passive: true });


Removing a listener

removeEventListener demands exactly the same arguments as the registration: same type, same function, same capture value. An anonymous function is built afresh on every evaluation, so it can never be found again.

JAVASCRIPT
const onClick = () => console.log("click");

button.addEventListener("click", onClick);
button.removeEventListener("click", onClick);          // removed
button.removeEventListener("click", () => console.log("click"));   // no effect

When several listeners have to disappear together, a shared AbortController cuts them all in one call.

Good to know

Registering the same function twice, for the same type and the same options, only adds it once: the duplicate is ignored. Two identical anonymous functions, however, count as two.


Why not onclick

The onclick property still works, but it holds a single function: the second assignment silently overwrites the first. Two pieces of code aiming at the same button then cancel out.

  • Several listeners live side by side without disturbing one another, in the order they were added.
  • Options such as once or capture do not exist with the property.


Frequently asked questions

Question

Why does my removeEventListener do nothing?

Because the function handed to the removal is not the one that was registered. Two functions with identical bodies are still two distinct objects. Store the listener in a const before adding it, or go through an abort signal.


Question

Do listeners have to be removed to free memory?

On an element taken out of the document and no longer reachable, the cleanup happens on its own. The real risk concerns listeners placed on document or window from a temporary component: those outlive the component and pile up on every opening.


Question

How do you handle hundreds of clickable elements?

By listening to a single one. Event delegation places the listener on a shared ancestor and identifies the real element at click time, which also covers content added later. That reflex and the traps around it are worked through step by step in the JavaScript course.

Related terms

Discover our javaScript glossary

Every word of JavaScript explained simply: keywords, built-in objects, methods, errors and concepts. Clear definitions and examples that actually run, to learn and to troubleshoot.

Share this article

Want to help us? Share this article on your networks or even better: on your site, in an article or in your newsletter.