How to Create One-Time Events in JavaScript

Share this article

Sometimes an event need only be called once in your page. For example, clicking a thumbnail which loads and plays a video file or clicking a “more” icon which retrieves and displays extra content via Ajax. However, you’ve probably defined an event handler which is called every time that action occurs. At best, it’s a little inefficient and the browser is retaining unnecessary resources. At worst, your handler could do something unexpected or reload data which is already available. Fortunately, it’s relatively easy to create one-time event handlers in JavaScript. The process:

  1. A handler is assigned to an event, such as clicking an element.
  2. When the element is clicked, the handler runs.
  3. The handler is removed. Further clicks on that element will no longer call the function.

jQuery

Let’s look at the simplest solution first. If you’re using jQuery, there’s a little-known one() event binding method which implements one-time events.
$("#myelement").one( "click", function() { alert("You'll only see this once!"); } );
It’s used identically to other jQuery event methods. For more information, refer to api.jquery.com/one/.

Self-Removing Handlers

If you’re using raw JavaScript, any handler function can remove itself using a single line of code:
document.getElementById("myelement").addEventListener("click", handler);

// handler function
function handler(e) {
	// remove this handler
	e.target.removeEventListener(e.type, arguments.callee);

	alert("You'll only see this once!");
}
Presuming your handler event argument is named ‘e’, the line:
e.target.removeEventListener(e.type, arguments.callee);
will remove the handler the first time it’s invoked. It doesn’t matter what event type or name you use for your handler — it may even be an in-line anonymous function. Note I’ve used standard event calls which won’t work in IE8 and below. OldIE’s require a call to detachEvent and the type requires an “on” prefix, e.g. “onclick”. But, if you’re supporting oldIE’s, you’re probably using jQuery or your own custom event handler. Self-removing handlers may be the best option if you require some flexibility, e.g. you only want to unhook certain event types or remove the handler after different conditions, e.g. two or more clicks.

A One-Time Event Creation Function

Like me, you may be too lazy or forgetful to add an event removal line to every handler function. Let’s create a onetime function which does the hard work for us:
// create a one-time event
function onetime(node, type, callback) {

	// create event
	node.addEventListener(type, function(e) {
		// remove event
		e.target.removeEventListener(e.type, arguments.callee);
		// call handler
		return callback(e);
	});

}
We can now use this function whenever we require a one-time only event:
// one-time event
onetime(document.getElementById("myelement"), "click", handler);

// handler function
function handler(e) {
	alert("You'll only see this once!");
}
While you won’t require one-time events in every page, it’s good to find there are several options available to JavaScript developers.

Frequently Asked Questions (FAQs) about Creating One-Time Events in JavaScript

How can I add an event for a one-time click to a function in JavaScript?

In JavaScript, you can add a one-time event to a function using the addEventListener method with the {once: true} option. This option ensures that the event listener is invoked only once after it is added. Here’s an example:

document.querySelector('#myButton').addEventListener('click', function() {
console.log('Button clicked!');
}, {once: true});

In this code, the event listener is added to the button with the ID ‘myButton’. When the button is clicked, the message ‘Button clicked!’ is logged to the console. After the button is clicked once, the event listener is removed, so clicking the button again will not log the message.

What is the equivalent of JavaScript’s addEventListener method in jQuery?

In jQuery, the equivalent of JavaScript’s addEventListener method is the one method. This method attaches one or more event handlers for specified events, and the event handler is executed at most once per element per event type. Here’s an example:

$('#myButton').one('click', function() {
console.log('Button clicked!');
});

In this code, the event handler is added to the button with the ID ‘myButton’. When the button is clicked, the message ‘Button clicked!’ is logged to the console. After the button is clicked once, the event handler is removed, so clicking the button again will not log the message.

How can I force my JavaScript event to run first, regardless of the order in which the events were added?

In JavaScript, the order in which event listeners are added determines the order in which they are executed. However, you can use the event.stopPropagation() method to prevent further propagation of the current event in the capturing and bubbling phases. This means that if you add an event listener that calls event.stopPropagation(), and add it before any other event listeners, it will be the first (and only) one to run. Here’s an example:

document.querySelector('#myButton').addEventListener('click', function(event) {
event.stopPropagation();
console.log('First event listener');
});

document.querySelector('#myButton').addEventListener('click', function() {
console.log('Second event listener');
});

In this code, the first event listener stops the propagation of the click event, so the second event listener is never invoked, even though it was added after the first one.

How can I remove an event listener in JavaScript?

In JavaScript, you can remove an event listener using the removeEventListener method. This method requires the same parameters as the addEventListener method: the event type and the event handler function. Note that in order to remove an event listener, you must pass the exact same function to removeEventListener as you passed to addEventListener. Here’s an example:

function handleClick() {
console.log('Button clicked!');
}

document.querySelector('#myButton').addEventListener('click', handleClick);
document.querySelector('#myButton').removeEventListener('click', handleClick);

In this code, the handleClick function is added as an event listener to the button with the ID ‘myButton’. Then, the same function is removed as an event listener from the button. After the removeEventListener line, clicking the button will not log the message.

How can I add a one-time event to multiple elements in JavaScript?

In JavaScript, you can add a one-time event to multiple elements using the querySelectorAll method and the forEach method. The querySelectorAll method returns a NodeList of all elements that match a specified CSS selector, and the forEach method executes a provided function once for each NodeList element. Here’s an example:

document.querySelectorAll('.myButtons').forEach(function(button) {
button.addEventListener('click', function() {
console.log('Button clicked!');
}, {once: true});
});

In this code, the event listener is added to all buttons with the class ‘myButtons’. When any of these buttons is clicked, the message ‘Button clicked!’ is logged to the console. After a button is clicked once, the event listener is removed from that button, so clicking the same button again will not log the message.

Craig BucklerCraig Buckler
View Author

Craig is a freelance UK web consultant who built his first page for IE2.0 in 1995. Since that time he's been advocating standards, accessibility, and best-practice HTML5 techniques. He's created enterprise specifications, websites and online applications for companies and organisations including the UK Parliament, the European Parliament, the Department of Energy & Climate Change, Microsoft, and more. He's written more than 1,000 articles for SitePoint and you can find him @craigbuckler.

JavaScriptjQuery
Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week