How to Create Custom Event in Javascript

In this tutorial, you will learn how to create custom event in javascript. Events play very important in a web application.  It is completely impossible to create a web application without making use of events.  In javascript, we have a lot of built-in events for specific situation such as click, change, load, DOMContentLoaded etc.

Click event is triggered when user clicks on some element such as button. DOMContentLoaded event is triggered when browser has loaded and parsed HTML.  It does not consider whether other parts of web page are loaded or not such as images, stylesheets or subframes.

If you want to make sure that complete web page is loaded by the browser including images, stylesheets and subframes, then you should listen for load event.

Why do you need a Custom Event?

In most of the cases, these built-in events will suffice for basic requirements of a web application.  But in some situation, we need to have some custom event to make our application more interactive and user-friendly.

Having a custom event will enhance user experience of your web application. Custom events help in the better management of the state in the web application.

For instance, you are developing an application where user has to login. When the user clicks on the login button, your application will make a request to the server and get the response.

Now, based on the response you may want to show error or success message in the UI and redirect the user to the dashboard.  There is no built-in event in javascript to achieve this solely based on response.  But fortunately in javascript, we can create a custom event, attach it to any element in the DOM and trigger it whenever we want.

Creating Event Using Event Constructor

In javascript, a custom event can be created using Event constructor. Event constructor takes 2 parameters. First parameter represents event name and it should be in string format. Second parameter is optional and it should be an object with 3 optional properties (bubbles, cancelable, composed).

bubbles: This indicates whether the event bubbling should occur or not.  It will be either true or false. The default value for this property is false.

If you set it to true and want event bubbling to reach up to a particular element, but not beyond that, then you can make use of event.stopPropagation() in that particular element.

cancellable: This indicates whether the event can be cancelled or not. It will be either true or false. In javascript, the default behavior of an event can be prevented by using event.preventDefault() method.

If you set cancellable to false, then event.preventDefault() method will have no impact on this particular event. The default value for this property is false.

composed: This indicates whether the event should trigger listeners outside the shadow DOM. It will be either true or false. Shadow DOM is created when you are using web components.

If you set this to true and dispatch the event from web component, then any HTML elements outside the shadow DOM can listen and react to it. The default value for this property is false and I suggest you to keep it that way until or unless you are aware how shadow DOM works.

Event Constructor Example

This is very basic example of Event constructor. Please have a look over step given below to understand better.

  • We have 2 elements in our HTML page (button and h1). We got reference of those elements using querySelector() method.
  • We created custom event myEvent using Event constructor.
  • We attached click event listener to button.
  • We need custom event listener, so we attached custom event myEvent to h1 element.
  • We dispatched or triggered myEvent on button click, which in result will display “Hi John” in the h1 tag.
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
       <button>Click Here</button> 
       <h1>Status</h1>
    <script src="script.js"></script>
</body>
</html>
let btnElement = document.querySelector("button");
let status = document.querySelector("h1");

// create event
var event = new Event("myEvent");

btnElement.addEventListener("click", () => {
  status.dispatchEvent(event);
});

// add event listener
status.addEventListener("myEvent", function (e) {
  status.innerText = "Hi John";
});

Creating Event Using CustomEvent Constructor

We can also create custom events using CustomEvent constructor.  It also takes 2 parameters similar to Event constructor with a slight difference in the object being passed as second parameter.

This object will have one more optional property detail. This detail property is extremely useful when you want to pass an additional data to the event listener. The default value for this property is null.

CustomEvent Constructor Example

This is very basic example of CustomEvent constructor. Please have a look over step given below to understand better.

  • We have 2 elements in our HTML page (button and h1). We got reference of those elements using querySelector() method.
  • We created custom event showName using CustomEvent constructor and provided custom data using detail property. Custom data is nothing more than an object with name property holding value “Peter”.
  • We attached click event listener to button.
  • We need custom event listener, so we attached custom event showName to h1 element.
  • We dispatched or triggered showName on button click.
  • Custom data is available in the event’s detail property. This means we can easily access name property in the custom data and display it in the h1 tag.
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
       <button>Click Here</button> 
       <h1>Status</h1>
    <script src="script.js"></script>
</body>
</html>
let btnElement = document.querySelector("button");
let status = document.querySelector("h1");

// create event
var event = new CustomEvent("showName", {
  detail: {
    name: 'Peter'
  }
});

btnElement.addEventListener("click", () => {
  status.dispatchEvent(event);
});

// add event listener
status.addEventListener("showName", function (e) {
  status.innerText = e.detail.name;
});

Custom Event vs Event

From the details mentioned above, it is very much clear that Event and CustomEvent constructors work pretty much the same.  In both cases, you need to create an event, attach custom event listener to a HTML element, and dispatch the event.  However, there is a very small difference.

CustomEvent constructor gives us an ability to send custom data to the event listeners whereas in the Event constructor we do not have such option.

My personal recommendation will be to use CustomEvent constructor.  Whether you are passing data or not, it fits the bill in both situations.

Custom Event Video Tutorial Source Code

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    
    <div style="text-align: center;">
        <button>Trigger Event</button>
        <h1>Result</h1>
    </div>
    <script src="script.js"></script>
</body>
</html>
let btnTrigger = document.querySelector('button');
let result = document.querySelector('h1');

btnTrigger.addEventListener('click', () => {
    let data = {
        name: 'John',
        backgroundColor: 'green',
        color: '#fff'
    }

    createAndTriggerEvent(data);
});

function createAndTriggerEvent(data){
    let myEvent = new CustomEvent('showName', {
        detail:data
    });
    
    result.dispatchEvent(myEvent);
}

result.addEventListener('showName', (e) => {    
    let {name, backgroundColor, color} = e.detail;
    result.innerText = name;
    result.style.backgroundColor = backgroundColor;
    result.style.color = color;
})