How to ensure an event listener is only fired once in JavaScript

Sometimes, we only need to listen once for an event. Imagine that we have a link to a file in the cloud that is not shared with us. In this case, the event listener bound to the button to give us permission to view the file should only be fired once as, once the request is processed, there is no need to process the request again.

This can be handled in two ways:

  • using the once option
  • removing the event listener after the event is fired for the first time

1. Using the once option

We can pass an object as an argument to the addEventListener method and specify that the event is only handled once. This is achieved by passing the property once to the object. If we set once to true, the event will only be fired once.

let btn = document.getElementById('btn');
btn.addEventListener("click", function() {

    // onClick code

}, {once : true});

2. Removing the event listener once the event is fired

We will bind an event listener for the element with the handler function and, inside the handler function, we will remove the event added for that element.

let btn = document.getElementById('btn');
function onClick(event){
   btn.removeEventListener('click', onClick);
   console.log("Event fired once, no more click will be handled");
}

btn.addEventListener('click', onClick);

The code below shows how to create a common function to handle all events and elements:

function oneTimeListener(node, type, callback) {
    // create event
    node.addEventListener(type, function listener(e) {

        // remove event listener
        e.target.removeEventListener(e.type, listener);

        // call handler with original context 
        return callback.call(this, e); 

    });
}

let btn = document.getElementById('btn');
function onClick(event){
   console.log(event, this);
}
oneTimeListener(btn, 'click', onClick);

In the code above, we have added an event listener to the DOM element. As soon as the event is fired for the first time, we remove the event listener bound to it. This way, it will be like the event was only handled once.