Event
The object the browser passes to every event handler. It describes what happened (click, keypress, submit) and gives you methods to control how it propagates.
When to use it
- User interactions — clicks, key presses, form submissions
- Preventing defaults — stopping a form from reloading or a link from navigating
- Delegation — one listener on a parent handles clicks for many children
- Custom events — fire your own events between components
Anatomy
element.addEventListener('click', (event) => {
event.type // 'click' — the event name
event.target // the element that was actually clicked
event.currentTarget // the element the listener is attached to
event.timeStamp // ms since page load
event.preventDefault() // stop the default browser behavior
event.stopPropagation() // stop the event from bubbling up the DOM
// mouse events
event.clientX // x position relative to viewport
event.clientY // y position relative to viewport
// keyboard events
event.key // 'Enter', 'a', 'Escape', etc.
event.code // 'KeyA', 'Enter' — physical key
event.shiftKey // true if shift was held
event.ctrlKey // true if ctrl/cmd was held
})At a glance
| Property / Method | What it gives you |
|---|---|
.type | Event name as a string |
.target | The element the event originated from |
.currentTarget | The element the listener is on |
.preventDefault() | Cancel the browser’s default action |
.stopPropagation() | Stop bubbling to parent elements |
.clientX / .clientY | Mouse position (viewport-relative) |
.key | Which key was pressed (keyboard events) |
.code | Physical key identifier |
.shiftKey / .ctrlKey / .altKey | Modifier key state |
.timeStamp | When the event fired (ms since page load) |
Common event types
| Type | When it fires |
|---|---|
| click | Mouse click or tap |
| submit | Form submitted |
| input | Input value changes (fires on every keystroke) |
| change | Input loses focus after value changed |
| keydown / keyup | Key pressed / released |
| focus / blur | Element gains / loses focus |
| mouseover / mouseout | Pointer enters / leaves an element |
| DOMContentLoaded | HTML parsed, DOM ready |
| load | Page and all resources fully loaded |
1. Simple — listen and inspect
const btn = document.querySelector('button')
btn.addEventListener('click', (e) => {
e.type // 'click'
e.target // the <button> element
e.target.textContent // the button's text
})2. Intermediate — event delegation
// one listener on the parent handles clicks for all <li> children
const list = document.querySelector('ul')
list.addEventListener('click', (e) => {
const item = e.target.closest('li') // find the <li> that was clicked
if (!item) return // click wasn't on an <li>
item.classList.toggle('done')
// e.target = the exact element clicked (could be a <span> inside <li>)
// e.currentTarget = the <ul> the listener is on
})3. Advanced — custom events
// define a custom event with a detail payload
const cartUpdate = new CustomEvent('cart:update', {
detail: { itemId: 42, qty: 2 },
bubbles: true, // allow it to bubble up like native events
})
// listen anywhere up the DOM tree
document.addEventListener('cart:update', (e) => {
e.detail.itemId // 42
e.detail.qty // 2
})
// dispatch from any element
document.querySelector('.add-btn').dispatchEvent(cartUpdate)Custom events let loosely coupled components communicate without direct references to each other.
Gotchas
target vs currentTarget
// <ul> listener, user clicks a <span> inside an <li>
list.addEventListener('click', (e) => {
e.target // <span> — the deepest element clicked
e.currentTarget // <ul> — the element with the listener
// use .closest() to find the ancestor you actually care about
e.target.closest('li') // the <li> containing the <span>
})Removing listeners requires a named function
// this won't work — anonymous functions can't be matched
el.addEventListener('click', () => console.log('hi'))
el.removeEventListener('click', () => console.log('hi')) // no effect
// use a named function instead
function handleClick() { console.log('hi') }
el.addEventListener('click', handleClick)
el.removeEventListener('click', handleClick) // worksRelated
- FormData — reads form field values after a submit event
- .forEach() — loop through a NodeList to add listeners
Last updated on