Reputation: 423
I have some JavaScript to execute logic i.e. doSomething()
when a button is clicked. I know the class of the buttons, but there are multiple buttons on the page with this same class. The problem with my code below is that the doSomething()
function is executed once for every button on the page when I only want it to execute one time only.
var myButtonClass = $(".my-button-class");
if (myButtonClass) {
myButtonClass.click(function (event) {
if (someCondition) {
doSomething();
}
});
}
I know it would be better to select by button div, but the button div names all vary based on how many there are (i.e. #my-button-div1
, #my-button-div2
, etc.) and the number of buttons is indefinite.
Is there a way to only do this event once? I don't care which button in the class happens to be clicked, I just need the event to fire once and then it's done.
UPDATE: To be clear, I still want the logic to execute if the user clicks another button on the page again, so I don't want to completely unbind the event. I just don't want it to execute once for every button on the page. For example, let's say I have 4 buttons. Right now it's doing something like the following when just one button is clicked:
alert!
alert!
alert!
alert!
I only need ONE of those alerts. Basically, whenever the user clicks any of the buttons on the page, I need it to go alert!
only once per click.
Upvotes: 2
Views: 2801
Reputation: 33466
If you give the handler a local boolean variable that is protected with a closure, you can create a function that will execute only once. See this SO answer.
Run the code snippet below to see it in action.
$(".my-button-class").click(function() {
var executed = false;
return function() {
if (!executed) {
executed = true;
doSomething();
}
};
}());
function doSomething() {
alert("You should only see me once!");
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="my-button-class">Click me!</button>
<button class="my-button-class">No click me!</button>
UPDATE: To address a different issue of the click event getting bound more than once. Just do a similar thing with:
var bind = function() {
var bound = false;
return function() {
if (!bound) {
bound = true;
$(".my-button-class").click(function() {
if (someCondition)
doSomething();
});
}
};
}();
bind();
bind(); // won't execute second time
var someCondition = true;
function doSomething() {
$("#output").append("<br>alert!");
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="my-button-class">Click me!</button>
<button class="my-button-class">No click me!</button>
<span id="output"></span>
Upvotes: 1
Reputation: 629
Revised so that you don't have weird if statements, and allows for other click handlers to happily work if binded elsewhere
UPDATED:
var clickHandler = function handleClick(event) {
doSomething();
}
var bindClicks = true;
function doSomething() {
alert('alert!');
}
function doTheBinding() {
if (bindClicks) {
$('.my-button-class').on('click', clickHandler);
bindClicks = false;
}
}
// as many times as you want but it will still call once
doTheBinding();
doTheBinding();
doTheBinding();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<button class="my-button-class">Click me!</button>
<button class="my-button-class">Click me!</button>
<button class="my-button-class">Click me!</button>
<button class="my-button-class">Click me!</button>
Upvotes: 2
Reputation: 87203
You can use on()
and off()
to bind and unbind the event on an element respectively.
$('.my-button-class').on('click', function (event) {
if (someCondition) {
doSomething();
// Unbind the event on all the elements having the class
$('.my-button-class').off('click');
// To unbind the event on only the clicked element
// $(this).off('click');
}
});
Sidenote: if (myButtonClass) {
will always evaluate to true
. jQuery returns an object even when the element is not found and an object is always truthy. To check if an element exists in DOM, use length
property on the jQuery object $('someSelector').length > 0
.
Upvotes: 1