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.
| Category | Events |
|---|---|
| Mouse | click, dblclick, mousedown, mouseup, mousemove, mouseenter, mouseleave |
| Keyboard | keydown, keyup, keypress (deprecated) |
| Form | submit, input, change, focus, blur |
| Window | load, resize, scroll, beforeunload |
| Touch | touchstart, 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.