I have the following code:
function someMethod()
{
$(obj).click(function {});
}
someMethod is called twice and thus click event is binded twice. How can I make it bind only once?
I have the following code:
function someMethod()
{
$(obj).click(function {});
}
someMethod is called twice and thus click event is binded twice. How can I make it bind only once?
If you can apply it, probably want to take a look at event.preventDefault and event.stopPropagation OR unbind and bind each time, within your method like
function someMethod()
{
$(obj).off('click').on('click', function(e) {
// put your logic in here
});
}
In addition to pna's answer you may wish to think about namespacing your event so you do not go around unbinding all the click events accidentally.
function someMethod() { $(obj).unbind('click.namespace').bind('click.namespace', function() { }); }
There is no built in method to determine if you have already bound this particular function. You can bind multiple click functions to an object. For example:
$('#id').bind('click', function(){
alert('hello');
});
$('#id').bind('click', function(){
alert('goodbuy');
});
if you do the above when the object is clicked it will alert hello then goodbye. To make sure only one function is bound to the click event unbind the click event handler then bind the desired function like this:
$(obj).unbind('click').bind('click', function(){... });
Or use jQuery's one() function which is similar to on() but only fires the event once, even if you bind it multiple times.
The obvious solution is to not call someMethod()
twice. If you can't fix that, then you can keep a state variable so it only ever binds once like this:
function someMethod()
{
if (!someMethod.bound) {
$(obj).click(function() {});
someMethod.bound = true;
}
}
Note: this uses a property of the function itself rather than introducing a global variable to keep track of whether it's been bound. You could also use a property on the object itself.
You can see it work here: http://jsfiddle.net/jfriend00/VHkxu/.
You can use this jQuery extension function.
$.fn.once = function (type, fn, uid) {
if(uid == undefined) {
console.error("Called $.once without uid\n", this, "\n", fn);
}
var dataStr = type+"-handler-"+uid;
if(!this.data(dataStr)) {
this.data(dataStr, true);
this.on(type, fn);
}
};
Instead of doing this
$("button").on("click", function(){
alert("You Clicked On A Button");
});
Ya do this
$("button").once("click", function(){
alert("You Clicked On A Button");
}, "btnHandler");
Now when I have a function around it
function addBtnHandler() {
$("button").once("click", function() {
alert("You Clicked On A Button");
}, "btnHandler");
}
And I call it multiple times
addBtnHandler();
addBtnHandler();
addBtnHandler();
It only does it once.
Notice that the extension works by checking both uid and type. This means that you can bind different types of handlers with the same uid, you may or may not want this. To change it edit.
var dataStr = type+"-handler-"+uid;
With something like
var dataStr = "handler-"+uid;
jQuery makes calling some function possible only once pretty easy:
function someMethod()
{
$(obj).click(function() {});
this.someMethod = $.noop;
}
You can add css class to the binded elements and then filter them out:
function someMethod()
{
$(obj).not('.click-binded')
.click(function {})
.addClass('click-binded');
}
This method may be used also for plugins:
$(obj).not('.datetimepicker-applied')
.datetimepicker()
.addClass('datetimepicker-applied');
This is a suggestion since I do not know your logic. May or may not work for you.
Try combining jquery live() and one() functions will give you a better result than event rebinds.
The special cases work when you have 2 DOM elements (parent & child). Live() at parent node makes sure event will be invoked, and then calls one() to dynamically register event which would be executed only once. (this provides similar functionality like rebinds).
I was also trying to use off and on method of jquery for binding event only once with the dom element which does not exists yet or the dom element is not yet created.
$('.select').off('event').on('event', 'selector', function(e){ // });
This code was not working properly
I came across a very lucrative method that is 'one' method. It is very useful when you want to bind an event only once.
You can find the document here https://api.jquery.com/one/
This is same as method 'on' but different with its behavior with not to stick with the event for multiple selectors.
$('body').one('click', 'selector', function(){ // do your stuff here });
var bound = false;
function someMethod()
{
if(!bound)
{
$(obj).click(function {});
bound = true;
}
}
but I would probably look into why it;s being called twice before making some kind of workaround.
You can achieve this with pure JS, using addEventListener method and his once option
target.addEventListener('click', handler, {once: true});