Events
An event is something that happens in the browser — a user clicking a button, pressing a key, moving the mouse, submitting a form, or a page finishing loading. JavaScript can listen for these events and run code in response.
Events make web pages interactive. Without them, a page would be static content that the user can only read.
// Listen for a click on a button
const btn = document.getElementById("myBtn");
btn.addEventListener("click", function () {
console.log("Button was clicked!");
});
addEventListener(event, handler) is the
recommended way to attach an event listener. You can
attach multiple listeners to the same element for the
same event type, and you can also remove them with
removeEventListener.
const btn = document.getElementById("btn");
function handleClick() {
console.log("Clicked!");
}
// Add listener
btn.addEventListener("click", handleClick);
// Remove listener (must pass the same function reference)
btn.removeEventListener("click", handleClick);
// Arrow function shorthand
btn.addEventListener("click", (event) => {
console.log("Event type:", event.type); // Output: click
console.log("Target element:", event.target);
});
The event object passed to the handler
contains useful information like the type of event, the
element that triggered it (event.target), and
methods to control the event behavior.
The click event fires when the user clicks on an element with the mouse or taps it on a touch screen.
const btn = document.getElementById("btn");
btn.addEventListener("click", function (e) {
console.log("Clicked at:", e.clientX, e.clientY);
// e.clientX/Y = mouse position relative to the viewport
});
The change event fires when the value of
a form field changes and the field loses focus. It is
commonly used with <input>,
<select>, and
<textarea>.
// HTML: <select id="color">
// <option value="red">Red</option>
// <option value="blue">Blue</option>
// </select>
const select = document.getElementById("color");
select.addEventListener("change", function (e) {
console.log("Selected:", e.target.value); // e.g. "blue"
});
For real-time updates as the user types, use the
input event instead of change.
Mouse events fire when the user interacts with a page using a mouse or trackpad. The most common ones are:
click— left button clickdblclick— double clickmouseover— pointer moves onto an elementmouseout— pointer leaves an elementmousemove— pointer moves over an elementmousedown— mouse button is pressedmouseup— mouse button is released
const box = document.getElementById("box");
box.addEventListener("mouseover", () => {
box.style.backgroundColor = "yellow";
});
box.addEventListener("mouseout", () => {
box.style.backgroundColor = "";
});
box.addEventListener("mousemove", (e) => {
console.log("Mouse at:", e.clientX, e.clientY);
});
Keyboard events fire when the user presses or releases a key. The two main events are:
-
keydown— fires when a key is first pressed (fires repeatedly if held) -
keyup— fires when the key is released
document.addEventListener("keydown", function (e) {
console.log("Key pressed:", e.key);
// e.key gives a readable name like "Enter", "a", "ArrowUp"
if (e.key === "Enter") {
console.log("Enter was pressed!");
}
});
document.addEventListener("keyup", function (e) {
console.log("Key released:", e.key);
});
Use e.key to get the name of the pressed
key. Use e.ctrlKey, e.shiftKey,
or e.altKey to check if modifier keys are
held.
When an event fires on an element, it bubbles up through the DOM tree to its parent elements. This means parent elements will also receive the event unless you stop it.
// HTML: <div id="parent"><button id="child">Click</button></div>
document.getElementById("child").addEventListener("click", () => {
console.log("child clicked");
});
document.getElementById("parent").addEventListener("click", () => {
console.log("parent clicked");
});
// Clicking the button outputs:
// child clicked
// parent clicked (event bubbled up!)
// To stop bubbling, call stopPropagation()
document.getElementById("child").addEventListener("click", (e) => {
e.stopPropagation();
console.log("only child");
});
By default, events are handled in the
bubbling phase (bottom-up). If you pass
true as the third argument to
addEventListener, the listener runs in the
capturing phase (top-down) instead.
The full event journey is: capturing phase (from the root down to the target), then the target itself, then the bubbling phase (back up to the root).
// HTML: <div id="parent"><button id="child">Click</button></div>
// useCapture = true means capturing phase
document.getElementById("parent").addEventListener("click", () => {
console.log("parent (capturing)");
}, true);
document.getElementById("child").addEventListener("click", () => {
console.log("child (bubbling)");
});
// Clicking the button outputs:
// parent (capturing) -- fires FIRST during capture phase
// child (bubbling)
Event delegation is a pattern where you attach a single event listener to a parent element instead of adding separate listeners to each child. Because events bubble up, the parent catches them all.
This is efficient for large lists or dynamically added elements because you don't need to add/remove listeners as items change.
// HTML: <ul id="list">
// <li>Item 1</li>
// <li>Item 2</li>
// </ul>
const list = document.getElementById("list");
// One listener on the parent handles clicks on all <li> children
list.addEventListener("click", function (e) {
if (e.target.tagName === "LI") {
console.log("Clicked:", e.target.textContent);
}
});
// Works even for items added to the list later
const newItem = document.createElement("li");
newItem.textContent = "Item 3";
list.appendChild(newItem); // No new listener needed
- An event is a signal that something happened in the browser.
- addEventListener is the standard way to respond to events.
- The event object passed to the handler has information about the event.
- click fires on mouse click or touch; change fires when an input value changes.
- Mouse events (mouseover, mouseout, mousemove) respond to pointer movement.
- Keyboard events (keydown, keyup) respond to key presses.
-
Event bubbling — events travel up from
the target to the root. Use
stopPropagation()to prevent this. -
Event capturing — the opposite
direction; enabled by passing
truetoaddEventListener. - Event delegation — attach one listener to a parent to handle events for all children.