I am binding a click event with a button:
$('#myButton').bind('click', onButtonClicked);
In one scenario, this is getting called multiple times, so when I do a trigger
I see multiple ajax calls which I want to prevent.
How do I bind
only if its not bound before.
This question is related to
jquery
As of June 2019, I've updated the function (and it's working for what I need)
$.fn.isBound = function (type) {
var data = $._data($(this)[0], 'events');
if (data[type] === undefined || data.length === 0) {
return false;
}
return true;
};
One more way - mark such buttons with a CSS class and filter:
$('#myButton:not(.bound)').addClass('bound').bind('click', onButtonClicked);
In recent jQuery versions replace bind
with on
:
$('#myButton:not(.bound)').addClass('bound').on('click', onButtonClicked);
Try:
if (typeof($("#myButton").click) != "function")
{
$("#myButton").click(onButtonClicked);
}
To avoid to check/bind/unbind, you can change your approach! Why don't you use Jquery .on() ?
Since Jquery 1.7, .live(), .delegate() is deprecated, now you can use .on() to
Attach an event handler for all elements which match the current selector, now and in the future
It means that you can attach an event to a parent element that is still existing and attach children elements whether they are present or not!
When you use .on() like this:
$('#Parent').on('click', '#myButton' onButtonClicked);
You catch event click on parent and it search child '#myButton' if exists...
So when you remove or add a child element, you do not have to worry about whether to add or remove the event binding.
if ($("#btn").data('events') != undefined && $("#btn").data('events').click != undefined) {
//do nothing as the click event is already there
} else {
$("#btn").click(function (e) {
alert('test');
});
}
I wrote a very tiny plugin called "once" which do that. Execute off and on in element.
$.fn.once = function(a, b) {
return this.each(function() {
$(this).off(a).on(a,b);
});
};
And simply:
$(element).once('click', function(){
});
Why not use this
unbind()
before bind()
$('#myButton').unbind().bind('click', onButtonClicked);
JQuery has solution:
$( "#foo" ).one( "click", function() {
alert( "This will be displayed only once." );
});
equivalent:
$( "#foo" ).on( "click", function( event ) {
alert( "This will be displayed only once." );
$( this ).off( event );
});
If using jQuery 1.7+:
You can call off
before on
:
$('#myButton').off('click', onButtonClicked) // remove handler
.on('click', onButtonClicked); // add handler
If not:
You can just unbind it first event:
$('#myButton').unbind('click', onButtonClicked) //remove handler
.bind('click', onButtonClicked); //add handler
Here's my version:
Utils.eventBoundToFunction = function (element, eventType, fCallback) {
if (!element || !element.data('events') || !element.data('events')[eventType] || !fCallback) {
return false;
}
for (runner in element.data('events')[eventType]) {
if (element.data('events')[eventType][runner].handler == fCallback) {
return true;
}
}
return false;
};
Usage:
Utils.eventBoundToFunction(okButton, 'click', handleOkButtonFunction)
The best way I see is to use live() or delegate() to capture the event in a parent and not in each child element.
If your button is inside a #parent element, you can replace:
$('#myButton').bind('click', onButtonClicked);
by
$('#parent').delegate('#myButton', 'click', onButtonClicked);
even if #myButton doesn't exist yet when this code is executed.
Based on @konrad-garus answer, but using data
, since I believe class
should be used mostly for styling.
if (!el.data("bound")) {
el.data("bound", true);
el.on("event", function(e) { ... });
}
Source: Stackoverflow.com