Event & Event Listener

Events are how the browser tells you that something happened: a click, a keypress, a form submission, the page finishing loading. Event listeners let you run code when those things happen.

I. addEventListener()

target.addEventListener(event, handler, options)
  • target: the element to watch (selected with a DOM selector)
  • event: a string naming the event, such as "click" or "keydown"
  • handler: a function to call when the event fires
  • options: optional; rarely needed for basic use
const button = document.querySelector(".btn");

button.addEventListener("click", function (event) {
  console.log("Button clicked", event.target);
});

You can also use an arrow function or a named function:

// Arrow function
button.addEventListener("click", (event) => {
  console.log("Clicked");
});

// Named function (easier to remove later)
function handleClick(event) {
  console.log("Clicked");
}
button.addEventListener("click", handleClick);

II. removeEventListener()

To remove a listener, pass the same function reference you used when adding it. Anonymous functions cannot be removed, which is why named functions are useful.

button.removeEventListener("click", handleClick);

III. Common event types

Mouse events

EventWhen it fires
clickMouse button pressed and released
dblclickDouble-click
mousedownMouse button pressed down
mouseupMouse button released
mouseoverCursor enters an element or any of its children
mouseenterCursor enters the element itself (does not bubble)
mouseleaveCursor leaves the element
mousemoveCursor moves over the element

Keyboard events

EventWhen it fires
keydownA key is pressed
keyupA key is released

Form and input events

EventWhen it fires
submitForm is submitted
inputInput value changes (any method)
changeInput loses focus with a changed value
focusElement receives focus
blurElement loses focus

IV. The event object

Every handler receives an event object with information about what happened.

button.addEventListener("click", (e) => {
  console.log(e.target);      // the element that was clicked
  console.log(e.type);        // "click"
  console.log(e.clientX);     // X position relative to viewport
  console.log(e.ctrlKey);     // true if Ctrl was held
});

Call e.preventDefault() to stop the browser’s default behaviour (for example, preventing a form from submitting):

const form = document.querySelector("form");
form.addEventListener("submit", (e) => {
  e.preventDefault();
  // handle submission with JavaScript instead
});

V. Event delegation

Instead of attaching a listener to each child element, attach one listener to a common parent and check which element triggered the event. This works for dynamically added elements too.

<ul class="list">
  <li>Item 1</li>
  <li>Item 2</li>
  <li>Item 3</li>
</ul>
const list = document.querySelector(".list");

list.addEventListener("click", (e) => {
  if (e.target.tagName === "LI") {
    console.log("Clicked:", e.target.textContent);
  }
});

One listener on ul handles clicks on all current and future li elements. This is more efficient than adding a listener to each item, especially for large or dynamic lists.