JavaScriptDOM and events

EventTarget.dispatchEvent()

Fires an event on an element from code. Together with CustomEvent, it lets you create custom events carrying extra data.

Returns
false if an event with cancelable: true was canceled by preventDefault(), otherwise true.
On this page

Example

#
JavaScript
const finish = document.querySelector('#finish')
const points = document.querySelector('#points')

document.addEventListener('lesson:complete', (event) => {
  const total = Number(points.textContent) + event.detail.points
  points.textContent = total
  console.log(`${event.detail.title}: +${event.detail.points} pts, total ${total}`)
})

finish.addEventListener('click', () => {
  const event = new CustomEvent('lesson:complete', {
    bubbles: true,
    detail: { title: 'Loops', points: 30 }
  })
  finish.dispatchEvent(event)
})

finish.click()
Console
Loops: +30 pts, total 150

The button announces that the lesson is complete, and the point counter listens on document. The event reaches it thanks to bubbles: true. Every click in the preview adds another 30 points.

Definition and usage

#

The dispatchEvent() method sends a prepared event object to an element, and the browser runs every handler function registered for that type. This happens synchronously: code written after dispatchEvent() only runs once every handler has finished.

You create an event with a constructor, e.g. new Event("input"), new KeyboardEvent("keydown", { key: "Enter" }), or new CustomEvent("name", { detail }). CustomEvent is for custom events: in the detail field you can pass any data, for example the number of points earned. That lets one part of an app announce “lesson complete”, while other parts react to it without knowing anything about each other.

An event created this way doesn’t bubble to parents by default, and can’t be canceled. The bubbles: true and cancelable: true options change that. The method returns false if some handler called preventDefault() on an event with cancelable: true, and true otherwise.

Events fired from code have event.isTrusted set to false. They also usually don’t trigger the browser’s default actions: an artificial keydown won’t type a character into a field, and a submit event won’t submit the form. The simplest way to simulate a click is element.click(), and to submit a form, form.requestSubmit().

Syntax

#
Syntax
target.dispatchEvent(event)

new Event(type, options)
new CustomEvent(type, { detail, bubbles, cancelable })

Parameters

#
  • event

    an Event object

    The event to send, created e.g. with new Event() or new CustomEvent().
  • type

    string (in the constructor)

    The event name. Name custom events so they don’t collide with built-in ones, e.g. "lesson:complete".
  • options

    optional object (in the constructor)

    detail (any data, only in CustomEvent), bubbles, and cancelable. Both of the latter default to false.

More examples

#
A synchronous call and isTrusted
JavaScript
const search = document.querySelector('#search')

search.addEventListener('input', (event) => {
  console.log('Searching:', search.value, '| isTrusted:', event.isTrusted)
})

search.value = 'python'
console.log('Before dispatchEvent()')
search.dispatchEvent(new Event('input'))
console.log('After dispatchEvent()')
Console
Before dispatchEvent()
Searching: python | isTrusted: false
After dispatchEvent()

The handler runs during dispatchEvent(), before the code continues. When you type something into the field in the preview, isTrusted will be true, since the user triggers the event.

Canceling an event and the method’s result
JavaScript
const leave = document.querySelector('#leave')
let unsavedChanges = true

leave.addEventListener('lesson:leave', (event) => {
  if (unsavedChanges) event.preventDefault()
})

function tryLeave() {
  const allowed = leave.dispatchEvent(new CustomEvent('lesson:leave', { cancelable: true }))
  console.log(allowed ? 'Leaving the lesson' : 'Save your changes first')
}

tryLeave()
unsavedChanges = false
tryLeave()
Console
Save your changes first
Leaving the lesson
Without bubbles, the parent never hears about it
JavaScript
const list = document.querySelector('#list')
const item = document.querySelector('#item')

list.addEventListener('task:done', () => console.log('List: task complete'))

item.dispatchEvent(new CustomEvent('task:done'))
console.log('Without bubbles, the list printed nothing')

item.dispatchEvent(new CustomEvent('task:done', { bubbles: true }))
Console
Without bubbles, the list printed nothing
List: task complete

Browser support

#

Widely available

Works in all modern browsers, phones included. You can use it without worry.

  • Chrome
  • Edge
  • Firefox
  • Safari

Good practices

#
  • Write custom event names in lowercase, with a prefix, e.g. "cart:add". That avoids collisions with the browser’s built-in events.
  • If an event should reach parents (e.g. a handler on document), set bubbles: true. By default it only reaches the element it was fired on.
  • Pass data in a CustomEvent’s detail field. Attaching custom properties to a plain Event is less readable.

Related entries

#

Spotted a mistake or missing an example? Write to us.