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
; })
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;
.addEventListener(evt, (e) => {
elif (!fired) fn(e);
= true;
fired ;
});
}
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.
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 )