How to dispatch custom events in JavaScript

Custom events can be dispatched in two ways:

  • using the Event constructor, which we use when we don’t need to send extra data.
  • using the CustomEvent constructor, which we use when we need to send extra data.

Create events using the Event constructor

To create a custom event using the Event constructor, we need the following:

  • eventType – name of the event (like “click” or “keydown”)
  • options (optional)
    • bubbles: true/false – the event “bubbles” if bubbles is true. The default value is false.
    • cancelable: true/false – the “default action” can be prevented by calling event.preventDefault() if cancelable is true. The default value is false.
    • composed: true/false – tells if an event can bubble across from the shadow DOM to the real DOM. The default value is false.

Take a look at the code below:

const myEvent = new Event('eventName', {
  bubbles: true,
  cancelable: true,
  composed: false
});
document.addEventListener('eventName', (e)=> {console.log(e)});

We can trigger our custom event by calling on an element by elem.dispatchEvent(customEventObj):

document.addEventListener('test', (e)=> {console.log(e)});
const customEvent = new Event('test', {
  bubbles: true,
  cancelable: true,
  composed: false
});

let parentDiv = document.getElementById('parent');
parentDiv.dispatchEvent(customEvent);

In the code above, we have triggered an event on the parentDiv element and added an event listener to the document. This checks if the bubbles option works.

Event bubbling means that when an event occurs on an element, it will run the element’s eventHandler first. Next, it runs the eventHandler of its parents up to its first parent.

If we set bubbles as false, then the above event listener will not be called:

// the event will not reach the document because we set bubbles to false . 
document.addEventListener('test', (e)=> {console.log(e)});
const customEvent = new Event('test', {
  bubbles: false,
  cancelable: true,
  composed: false
});

let parentDiv = document.getElementById('parent');
parentDiv.dispatchEvent(customEvent);

In the code above , the event will not reach the document because we triggered the event on parentDiv, setting bubbles to false. As a result, the event will not bubble to the document element.

Create native events

We have different native event objects like UIEvent, FocusEvent, MouseEvent ,WheelEvent, and KeyboardEvent. We can also create the following event:

document.addEventListener("click", (event) => {
   console.log("btn click");
});
let event = new MouseEvent("click", {
  bubbles: true,
  cancelable: true,
  clientX: 200,
  clientY: 900
});
let btn = document.getElementById('btn');
btn.dispatchEvent(event);

In the above code, we can define clientX and clientY. We cannot do so in the Event constructor:

let event = new Event("click", {
  bubbles: true,
  cancelable: true,
  clientX: 200,
  clientY: 900
});
event.clientX; // undeinfed 

However, we have a workaround to add a property to the Event object: just add the property like how you would add a property to an object:

let event = new Event("click");
event.clientX = 100;
event.clientX; // 100

Create events using the CustomEvent constructor

A CustomEvent can be created using the CustomEvent constructor, which takes two arguments:

  • eventType – the name of the event like “click” and “keydown”.
  • options(optional)
    • bubbles: true/false – the event bubbles if bubbles is true. The default value is false.
    • cancelable: true/false – the “default action” can be prevented by calling event.preventDefault() if cancelable is true. The default value is false.
    • composed: true/false – tells if an event can bubble across from the shadow DOM to the real DOM. The default value is false.
    • detail: event-specific data.
document.addEventListener('test', (e)=> {
   console.log(e.detail.name); // prints Anitha
});
let customEvent = new CustomEvent("test", {
  detail : {name :  "Anitha"},
  cancelable: true
});

let parentDiv = document.getElementById('parent');
parentDiv.dispatchEvent(customEvent);

event.isTrusted is true for user-generated events and false for script-generated events. By using this property, we can check if an event has been generated by the user or through the code.

Free Resources