Events
A web page is not a static document — it is a long-running program that reacts to things happening. A user clicks a button, types a key, scrolls the page, or a video finishes loading. Each of those is an event, and the DOM gives you a uniform way to listen for them and run code in response. Once you understand the event model, every interactive feature on the web is built from the same handful of pieces.
What an event actually is
An event is an object the browser creates whenever something noteworthy happens to a node. It is dispatched on a target — usually an element — and your code can register a function (a handler or listener) that runs when that target sees an event of a given type. The handler receives the event object as its argument.
Events are emitted by the browser, not by JavaScript itself. Mouse, keyboard, network, timer and lifecycle events all flow through the same DOM mechanism.
Every event has a
typestring ("click","keydown","submit") and atarget(the node it happened on).Most events also bubble up the tree — covered on a separate page.
The categories you will actually use
The HTML spec defines over a hundred event types. In day-to-day work you only need a handful, grouped by what they describe:
Mouse / pointer —
click,dblclick,mousedown,mouseup,mousemove,mouseenter,mouseleave,contextmenu, plus the unifiedpointerdown/pointermove/pointerupfamily that also handles touch and pen.Keyboard —
keydown,keyup. (Avoidkeypress— it is deprecated.)Form —
input,change,submit,reset,focus,blur.Window / document lifecycle —
DOMContentLoaded,load,beforeunload,pagehide,visibilitychange,resize,scroll.Media —
play,pause,ended,timeupdate,loadeddata.Drag & drop / clipboard —
dragstart,dragover,drop,copy,cut,paste.
Registering a handler — three ways
There are three ways to attach a click handler to a button. They look similar but behave very differently.
1. inline HTML attribute — avoid
<button onclick="alert('hi')">Click me</button>2. property assignment — single handler only
const btn = document.querySelector("button");
btn.onclick = () => alert("hi");
// Assigning again *replaces* the previous handler:
btn.onclick = () => alert("replaced");3. addEventListener — recommended
const btn = document.querySelector("button");
btn.addEventListener("click", () => alert("first"));
btn.addEventListener("click", () => alert("second"));
// Both run on each click — listeners stack.The property form is fine for tiny experiments, but addEventListener is the way you should reach for in real code: multiple listeners, options for capture and once, and a clear cleanup path with removeEventListener.
The event object
Every handler is called with a single argument — the event object. Different event types carry different details, but a few properties show up everywhere.
useful properties on every event
document.addEventListener("click", (event) => {
event.type; // "click"
event.target; // the element the event happened on
event.currentTarget; // the element whose listener is running (here: document)
event.timeStamp; // ms since the page loaded
event.isTrusted; // true if the user did it, false if dispatched by code
});Type-specific events add more. A MouseEvent carries clientX / clientY and button. A KeyboardEvent carries key and code. An InputEvent carries data and inputType. The MDN page for each event type lists exactly what is on it.
target vs currentTarget
These two trip people up. target is where the event originated — usually what the user actually interacted with. currentTarget is the element whose listener is currently running. They only differ when the event has bubbled up from a descendant.
<ul id="list"> <li>Apples</li> <li>Oranges</li> </ul>
document.getElementById("list").addEventListener("click", (e) => {
console.log("target:", e.target.tagName); // "LI"
console.log("currentTarget:", e.currentTarget.id); // "list"
});target: LI currentTarget: list
This distinction is the foundation of event delegation, which we cover in its own page.
A first interactive example
counter.html
<button id="inc">+1</button> <span id="count">0</span>
counter.js
const btn = document.getElementById("inc");
const out = document.getElementById("count");
let n = 0;
btn.addEventListener("click", () => {
n += 1;
out.textContent = String(n);
});Every click dispatches a MouseEvent on the button, your listener runs, you mutate state, you update the DOM, the browser repaints. That loop — event in, state change, DOM update — is the heartbeat of every interactive page.
Programmatically dispatching events
You can also fire events from code. This is useful in tests and in custom components that want to broadcast their own signals.
const btn = document.querySelector("button");
// fire a synthetic click
btn.dispatchEvent(new MouseEvent("click", { bubbles: true }));
// custom event with a payload
const ready = new CustomEvent("app:ready", { detail: { version: 3 } });
window.dispatchEvent(ready);
window.addEventListener("app:ready", (e) => console.log(e.detail.version));