Creating/Dispatching Custom JS Events
Tags: javascript, tutorial, beginners
Published: 2019-06-26 03:34:11

Here's a quick introduction to creating and dispatching custom events. Much like `click` and `change`, we're also able to create, have elements watch for, and trigger our very own events.

There's two API's provided that we can access:

[Event](https://developer.mozilla.org/en-US/docs/Web/API/Event/Event):
- Few config options
- Straight forward
- Creates a new event

[CustomEvent](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent):
- Same as `Event`
- Flexible
- Customizable config object


## Simple custom events

```js
/**
 * Simple custom event
 */
// Grab a reference to the <p> element
const p = document.querySelector('p')

// create a new event
const pEvent = new Event('pEvent')

// listen for the 'pEvent' on the <p> element
p.addEventListener('pEvent', e => {
  console.log('pEvent')
})

// trigger, or 'dispatch', the 'pEvent' event
p.dispatchEvent(pEvent)  // -> 'pEvent'
```

## Add 'Event Bubbling' to a custom event

```js
/**
 * Custom event with bubbling
 * Read more about 'bubbling' and 'capturing': https://javascript.info/bubbling-and-capturing
 */
const div = document.querySelector('div')
const divEvent = new Event('divEvent', { bubbles: true })

div.addEventListener('divEvent', e => {
  // should read 'Event dispatched from HTMLParagraphElement'
  console.log(`Event dispatched from ${e.target.constructor.name}`)
})

p.addEventListener('pEvent', e => {
  e.target.dispatchEvent(divEvent)
})

// Dispatch the event from the <p> element
// Notice that the event 'bubbles' up to the parent <div> tag
p.dispatchEvent(pEvent)
```

## Triggering events built into JS

```js
/**
 * Dispatching existing JS events (click, change, etc.)
 */
const button = document.querySelector('button')

button.addEventListener('click', () => {
  console.log('Button Clicked')
})

button.dispatchEvent(new Event('click'))  // Dispatch click using 'dispatchEvent'
button.click()  // Directly calling 'click' also works in this example
```

[repl.it example of these examples in action](https://repl.it/@bbenefield89/CreatingDispatching-Custom-JS-Events)

## Example of when to use

Say, for example, you don't have access to the code base of a project you've been assigned. Say, for example, you can only use plain JavaScript. Now, let's say the project you're working on is using a hodgepodge of HTML/CSS/JS and Vue components all hanging out on the same page.

Now in this scenario, you need to access a method on an input that's triggered by the inputs `change` event, something along the lines of `<input class="my_input" :onChange="makeChange" />`, but only after a button on the page has been clicked. Well, if we're injecting a script and we don't have access to any of the components methods and properties this could be a pretty challenging task.

The quick and easy solution here is to dispatch the elements `change` event similar to the examples above.

```js
const myInput = document.querySelector('.my_input')
const myButton = document.querySelect('.my_button')

myButton.addEventListener('click', () => {
  // dispatches the inputs 'change' event
  myInput.dispatchEvent(new Event('change'))
})
```