Events

React to what users do. Clicks, keys, scrolls, and more.

addEventListener

Attach a function that runs when an event occurs.

// Basic syntax:
element.addEventListener(eventType, handler);

// Example:
const btn = document.querySelector("button");

btn.addEventListener("click", () => {
  console.log("Button clicked!");
});

addEventListener takes an event type (string) and a handler function. The handler runs every time that event fires on the element.

1 / 2

The Event Object

Every handler receives an event object with useful info.

btn.addEventListener("click", (event) => {
  // What was clicked:
  event.target;        // element that triggered event
  event.currentTarget; // element listener is attached to
  
  // Event info:
  event.type;          // "click"
  event.timeStamp;     // when it happened
  
  // Mouse position:
  event.clientX;       // x relative to viewport
  event.clientY;       // y relative to viewport
  event.pageX;         // x relative to page
  event.pageY;         // y relative to page
  
  // Keyboard (for key events):
  event.key;           // "Enter", "a", "ArrowUp"
  event.code;          // "KeyA", "Space", "Enter"
  event.shiftKey;      // true if Shift was held
  event.ctrlKey;       // true if Ctrl was held
  
  // Control:
  event.preventDefault();  // stop default behavior
  event.stopPropagation(); // stop bubbling
});

Common Events

The events you'll use most often.

CategoryEvents
Mouseclick, dblclick, mousedown, mouseup, mousemove, mouseenter, mouseleave
Keyboardkeydown, keyup, keypress (deprecated)
Formsubmit, input, change, focus, blur
Windowload, resize, scroll, beforeunload
Touchtouchstart, touchmove, touchend
// Keyboard shortcuts:
document.addEventListener("keydown", (e) => {
  if (e.ctrlKey && e.key === "s") {
    e.preventDefault(); // stop browser save
    saveDocument();
  }
});

// Input (fires on every keystroke):
input.addEventListener("input", (e) => {
  console.log("Current value:", e.target.value);
});

// Change (fires when field loses focus):
select.addEventListener("change", (e) => {
  console.log("Selected:", e.target.value);
});

Removing Listeners

Clean up listeners to prevent memory leaks.

// Must use a NAMED function (not anonymous):
function handleClick(e) {
  console.log("Clicked!");
}

btn.addEventListener("click", handleClick);

// Later — remove it:
btn.removeEventListener("click", handleClick);

// ❌ This WON'T work (different function reference):
btn.addEventListener("click", () => console.log("hi"));
btn.removeEventListener("click", () => console.log("hi"));
// These are two different functions!

// ✓ Use AbortController (modern approach):
const controller = new AbortController();

btn.addEventListener("click", handleClick, {
  signal: controller.signal
});

// Remove all listeners added with this controller:
controller.abort();

💡 Use { once: true } for handlers that should only fire once — no manual removal needed.

Event Delegation

One listener on the parent handles all children.

// ❌ Bad: listener on every item
const items = document.querySelectorAll("li");
items.forEach(item => {
  item.addEventListener("click", handleClick);
});
// 100 items = 100 listeners = 100x memory
// New items won't have listeners!

Adding listeners to every element wastes memory and doesn't work for dynamically added elements.

1 / 2

FAQ

Common questions about events.