How can I execute an event handler at most once?

JavaScript, Browser, Event · Jun 12, 2021

jQuery

Back in the day when jQuery was all the rage, we would usually use $.one() to create an event handler that would execute at most once for a given event per element. A simple example would be as follows:

<button id="my-btn">Click me!</button>
$('#my-btn').one('click', () => {
  console.log('Hello!');  // 'Hello!' will only be logged on the first click
});

Using a flag

However, jQuery seems to have fallen out of favor lately and thus many developers have resorted to writing their version of $.one(). An implementation could look like this:

const listenOnce = (el, evt, fn) => {
  let fired = false;
  el.addEventListener(evt, (e) => {
    if (!fired) fn(e);
    fired = true;
  });
};

listenOnce(
  document.getElementById('my-btn'),
  'click',
  () => console.log('Hello!')
);  // 'Hello!' will only be logged on the first click

In this implementation, we use a flag, fired, to check if the event has been triggered before and only execute the passed callback, fn, the first time the event is triggered. There are some details that we might have omitted such as removing the listener, but overall this is a reasonably solid implementation.

Event listener options

If you are targeting modern browsers (i.e. not IE), EventTarget.addEventListener() has introduced the options object parameter, which allows us to pass a few different flags, one of which is once. Setting once to true results in the exact same behavior as the snippet above with minimal effort.

Here's one way to write the previous snippet using once, which also happens to be how we implemented the latest version of the listenOnce snippet:

const listenOnce = (el, evt, fn) => el.addEventListener(evt, fn, { once: true });

listenOnce(
  document.getElementById('my-btn'),
  'click',
  () => console.log('Hello!')
);  // 'Hello!' will only be logged on the first click

More like this

  • JavaScript Event Handling

    Event handling needs to be done right in JavaScript. Pick up some tips and tricks to create a better user experience.

    Collection · 15 snippets

  • Listen for an event only once

    Adds an event listener to an element that will only run the callback the first time the event is triggered.

    JavaScript, Browser · Oct 22, 2020

  • Add multiple listeners

    Adds multiple event listeners with the same handler to an element.

    JavaScript, Browser · Oct 22, 2020

  • Add event listener to all targets

    Attaches an event listener to all the provided targets.

    JavaScript, Browser · Apr 22, 2021