Events in JavaScript

Introduction

Events notify your code when users click, type, submit forms, or when media and network activity completes. You register listeners on DOM nodes (or window) and run handlers—often asynchronously. Events are the main bridge between UI and logic in browser apps.

Prerequisites

addEventListener

html
<!-- events.html -->
<button id="save">Save</button>
<script>
  const btn = document.getElementById("save");
 
  btn.addEventListener("click", () => {
    console.log("saved");
  });
</script>

Prefer addEventListener over inline onclick attributes for separation of concerns.

The Event Object

javascript
// Handler receives event
btn.addEventListener("click", (event) => {
  console.log(event.type);
  console.log(event.target);
});

Common fields: type, target, currentTarget, preventDefault(), stopPropagation().

preventDefault on Forms

html
<form id="signup">
  <input name="email" />
  <button type="submit">Join</button>
</form>
<script>
  document.getElementById("signup").addEventListener("submit", (e) => {
    e.preventDefault();
    console.log("handle signup in JS");
  });
</script>

Stops full page reload on submit until you wire real validation.

Event Propagation (Bubbling)

html
<div id="outer">
  <button id="inner">Click</button>
</div>
<script>
  document.getElementById("outer").addEventListener("click", () => {
    console.log("outer");
  });
  document.getElementById("inner").addEventListener("click", (e) => {
    console.log("inner");
    e.stopPropagation();
  });
</script>

Clicks bubble from child to ancestors unless stopped.

Delegation

Attach one listener on a parent for many dynamic children:

html
<ul id="list"></ul>
<script>
  const list = document.getElementById("list");
  list.innerHTML = "<li data-id='1'>One</li><li data-id='2'>Two</li>";
 
  list.addEventListener("click", (e) => {
    const li = e.target.closest("li");
    if (!li) return;
    console.log("picked", li.dataset.id);
  });
</script>

Keyboard and Input

javascript
// input event fires on every change
const input = document.querySelector("input");
input?.addEventListener("input", (e) => {
  console.log(e.target.value);
});

Mini Example: Toggle Class on Click

html
<button id="theme">Toggle theme</button>
<script>
  const root = document.documentElement;
  document.getElementById("theme").addEventListener("click", () => {
    root.classList.toggle("dark");
    console.log(root.className);
  });
</script>

FAQ

click vs mousedown?

click after press+release on same element; lower-level events fire earlier.

Passive listeners?

{ passive: true } improves scroll performance—required knowledge for touch/wheel optimizations.

Remove listeners?

removeEventListener with same function reference—arrow inline functions are harder to remove.

What comes next?

DOM manipulation.