DOM Events Table
| Event | Fires when | Typical target | Field note |
|---|---|---|---|
click | Pointer/Enter activation | Any element | Both mouse and keyboard (Enter) fire it |
input | Value changed on the fly | input, textarea, select | Fires every keystroke - live validation |
change | Value committed | input, select, textarea | Fires on blur or selection, not per keystroke |
submit | Form being sent | form only | Cancel with preventDefault() to validate first |
keydown / keyup | Physical key pressed/released | document, inputs | keydown repeats while held; use e.key |
focus / blur | Focus gained/lost | inputs, buttons, links | Do not bubble - delegate with focusin/focusout |
mouseenter / mouseleave | Pointer enters/leaves element | Any element | No bubbling - no flicker on children |
scroll | Scroll position moved | window, scrollable elements | Throttle it - fires at display rate |
resize | Viewport dimensions changed | window | Debounce before layout-heavy work |
DOMContentLoaded | DOM parsed, no waiting for images | document | The safe init point for scripts |
load | Everything including images arrived | window, img | Late but complete - analytics likes it |
pointerdown / pointerup | Unified mouse/touch/pen press | Any element | The modern replacement for mouse+touch pairs |
touchstart / touchend | Finger touch began/ended | Touch devices | Passive by default on document - preventDefault needs care |
error | Resource or script failed | img, script, window | The only hook for broken image fallbacks |
input fires per keystroke while change waits for commitment - search-as-you-type wants input, dropdown analytics wants change; and focus/blur do not bubble, so event delegation needs their bubbling cousins focusin/focusout. Bottom line: pointer events are replacing the mouse/touch double bookkeeping - new code starts there. Related tools: JS array methods table, XPath cheatsheet for selection, json formatter for the payloads events carry.Every interactive page is a conversation of events: the browser announces what the user did, your code decides what it means. The table below is the working vocabulary - fourteen events that cover nearly every interface you will build - with when each fires, its typical target, and the field note that prevents the classic bug.
Bottom line: input fires on every keystroke and change waits for commitment - search-as-you-type wants input, dropdown analytics wants change, and mixing them up is the most common event bug in the wild. The second most common: focus and blur do not bubble, so event delegation silently fails on them until you switch to focusin and focusout.
The honest part: the events table has been quietly consolidating for years. Pointer events (pointerdown, pointerup) now subsume the mouse and touch families in one unified model, and passive touch listeners changed how scroll performance works. New code starts with pointer events; the mouse and touch rows remain for the code you will inherit.
How to use
- Find the user action in the Fires-when column; the event name is in the first.
- Check the target column before attaching - submit only exists on forms, load only on window and media elements.
- Read the note column for the trap: bubbling behavior, repeat firing, passive listeners, cancelation semantics.
Frequently asked questions
What is the difference between the input and change events?
input fires immediately, on every modification - each keystroke, each paste, each spinner click. change fires when the value is committed: on blur for text inputs, immediately for checkboxes and selects. Live validation, character counters and search filtering want input. Sending analytics or recalculating something expensive wants change. A search box wired to change feels broken because it only reacts when the user clicks away.
Why does event delegation fail for focus and blur?
Because focus and blur do not bubble - they fire on the target element and stop. The delegation pattern (one listener on a parent, reading event.target) depends on bubbling, so it never sees them. The standard fix is their bubbling twins: focusin and focusout fire identically but propagate up the tree. Same names, same meaning, one difference that matters exactly when you adopt delegation.
Should I handle touch events separately from mouse events?
Not in new code. Pointer events unify mouse, touch and pen behind one interface - pointerdown, pointermove, pointerup - with pointerType telling you which. The legacy mouse and touch families still fire (often in a synthesized sequence: touchstart, then the emulated mouse events), which is how double-firing bugs are born. Listen to pointer events first and add touch-specific handling only for gestures like swipe or pinch.
When exactly does DOMContentLoaded fire versus load?
DOMContentLoaded fires when the HTML is fully parsed and all deferred scripts have run - the DOM is ready - without waiting for stylesheets, images or iframes. load fires when everything, including images and frames, has arrived. Scripts that wire up behavior belong behind DOMContentLoaded (or better, the defer attribute); analytics that need image beacons or full-page timing wait for load. Betting behavior on load makes a slow image server feel like a broken page.