I have a function that registers an event handler with a callback that will receive only some of the event data.
My problem is I want to protect against the function registering multiple time by calling .off before .on but I'm not sure how to specify the callback to .off in this case as it has to be the same function used by .on
For example:
function myclick(elem, callback) {
//elem.off('click', ???? ); // how should this be specified
elem.on('click', function (e) {
callback(e.target);
}
}
I am looking for a general solution that is not jQuery dependent as this can happen with any library that provides on and off functionality.
One way to do this is to use event namespacing which will make sure that only the handlers with the given namespace is removed others are not.
function myclick(elem, callback) {
elem.off('click.myradomnamespace').on('click.myradomnamespace', function (e) {
callback(e.target);
}
}
But if you are doing this to handle dynamic element's use event delegation
The next param is the delegate(function) you was passed before, if you dont know which delegatewas passed before, just simple pass '**' to delete all delegate:
elem.off('click', '**');
For more refer: http://api.jquery.com/off/
Hope this can help you!
Related
I'm using jQuery and I have a function that serves as an event callback, and so in that function "this" represents the object that that captured the event. However, there's an instance where I want to call the function explicitly from another function - how do I set what "this" will equal within the function in this case?
For example:
function handleEvent(event) {
$(this).removeClass("sad").addClass("happy");
}
$("a.sad").click(handleEvent); // in this case, "this" is the anchor clicked
function differentEvent(event) {
$("input.sad").keydown(e) {
doSomeOtherProcessing();
handleEvent(e); // in this case, "this" will be the window object
// but I'd like to set it to be, say, the input in question
}
}
Use apply call.
handleEvent.call(this, e);
Just parameterize the function you're interested in:
function doStuff(el) {
$(el).removeClass("sad").addClass("happy");
}
function handleEvent(event) {
doStuff(this);
}
$("a.sad").click(handleEvent); // in this case, "this" is the anchor clicked
function differentEvent(event) {
$("input.sad").keydown(e) {
doSomeOtherProcessing();
doStuff(this);
}
}
Use
e.target
I'd advice you re-factoring your function as a jQuery plugin.
But here's a quick Fix:
handleEvent.apply(this,e) //transfers this from one scope, to another
If you're simply looking to call a single event handler as if it were being triggered normally, apply/call will work fine. However, depending on your needs, it may be more robust to use the zero-argument version of jQuery's click() function, which will trigger all click handlers for that element:
function differentEvent(event) {
$("input.sad").keydown(e) {
doSomeOtherProcessing();
$(this).click(); // simulate a click
}
}
I am trying to override the default behavior of the jQuery event handlers. But can't seem to find any documentation on how to do this.
Say I'm binding a click handler to an element like this:
$('div#mydiv').on('click', funcName);
What I'm trying to accomplish is to overwrite the .on function, so I can modify the way any event is bound by jQuery
I've already tried overriding $.fn.on and that obviously caused a never ender loop:
$.fn.on = function(eventname, callback){
console.log(eventname + ' will be bound');
$(this).on(eventname, callback);
};
$(function(){
$('#element').on('click', function(){
console.log('Did execute click');
});
});
What is the proper way to hook into the event binding process? Also worth mentioning: I really just want to alter the way .on works, wrapping it into a different function wouldn't work for my case.
You need to cache the original function reference like so
var originalOn = jQuery.fn.on;
jQuery.fn.on = function() {
console.log(arguments[ 0 ] + ' will be bound');
originalOn.apply( this, arguments );
};
Here, we store the reference to jQuerys original .on function. Then we overwrite the handler, but we invoke the original function with the same context + arguments using Function.prototype.apply.
I have an element in a webpage which has several callbacks on it
// First callback
$("#element").click(fn1);
// Second callback
$("#element").click(fn2);
// Definitions
function fn1(){console.log("1");}
function fn2(){console.log("2");}
Is there a way to remove only fn2 from the list of callbacks triggered by jQuery.
I know I could add an 'if' inside the function and some global variable, but that's not what I'm looking for.
The second parameter in the unbind function specifies the handler to unbind.
$("#element").unbind("click", fn2);
Working Example: http://jsfiddle.net/k73Nx/
Interesting that nobody mentioned namespaces yet. Is there a reason for that?
When attaching your event, you can namespace it. Instead of $(elem).on('click', fn) you would add a namespace to the click event. $(elem).on('click.namespaced', fn)
When unbindung, you can then unbind that exact event, using the namespace as well.
$(elem).off('click.namespaced')
This is most practical when you're defining your event function inline.
One more thing you can do with namespaces is to unbind all event types within a namespae with just a single call: $(elem).off('.namespaced')
Be careful with your syntax here, other answers are very loose with theirs.
If you use:
$('#element').on('click',function() {
//callback code
});
Then you must use:
$('#element').off('click');
You cannot use
$('body').off('click','#element',function() { });
or
$(document).off('click','#element',function() { });
because you originally bound your event to #element, not to document or body.
Use unbind: http://api.jquery.com/unbind/
Example:
$(document).unbind('click', fn2);
use .off
$("#element").off("click",fn2);
working fiddle
I have some events like click, dblclick that are attached on large number of elements. To unbind click and dblclick events with all the elements at once I used this in jquery :
$(document).unbind("click").unbind("dblclick");
Now I have to rebind these events to all the elements again. For this I used :
$(document).bind("click").bind("dblclick");
But this is not working. Events are not rebind. How can I do this?
$(document).bind("click").bind("dblclick");
I don't think this will bind anything, you need callbacks.
$(document).bind("click", onClick).bind("dblclick", onDbClick);
Also, in this case you might want to consider using namespaced events:
$(document).bind("click.myclick", onClick)
And then later unbind only this event, leaving the other click untouched.
$(document).unbind("click.myclick");
P.S. It's now considered better practice to use the new on, off methods for binding.
unbind:
$(document).off("click", myFunction);
bind:
$(document).on("click", myFunction);
function myFunction() {
alert('you clicked the document');
}
jQuery on() and off() would be the way to go, and when rebinding, the function would have to be passed in again, you can't just rebind and expect it to know what function to call.
The best way is to name the callback functions, just as #adeneo suggested. But sometimes you don’t know when the handlers are bound (f.ex in a plugin), or perhaps you added anonymous callbacks using something like:
$(document).click(function() {
// anonymous
});
then you can restore all those callbacks using the $._data object. Here is a function for you:
function restoreHandlers(elem, type) {
var orig = $._data(elem, 'events');
if ( type in orig ) {
return $.map(orig[type], function(o) {
return o.handler;
});
} else return [];
}
Use it like this (before you unbind):
var handlers = restoreHandlers(document, 'click');
then unbind:
$(document).off('click');
then rebind:
$.each(handlers, function(i, fn) {
$(document).on('click', fn);
});
What is difference between $(".anything").click() and $(".anything").bind(click)
$(".anything").click(function() {
});
$(".anything").bind('click', function() {
});
Nothing, click(function() { }) is just a shortcut for bind("click", function() { }).
From the jQuery docs:
The jQuery library provides shortcut methods for binding the standard event types, such as .click() for .bind('click').
You can read more about bind() here.
The first is a shortcut of the second. The second is actually wrong, click should have been quoted. Further, in the second you have the added benefit that you can bind the same function to multiple events, each separated by a space. E.g.
$(".anything").bind("click keypress blur", function() {
});
In that specific case, absolutely nothing.
However:
A) If you give .click() no argument, it triggers the event instead of setting the handler.
B) only .bind() lets you use the "namespaced" way of registering handlers:
$(whatever).bind('click.myEvent', function (e) { ... });
$(whatever).unbind('click.myEvent'); // Removes just that handler
See this post, which points to the JQuery source to show that .click(fn) just calls .bind('click', fn): jQuery: $().click(fn) vs. $().bind('click',fn);
I usually only use the latter if:
I want to bind multiple things, i.e. .bind('click focus', fn)
Just to maintain convention if I call unbind later, i.e.:
var fn = function() { alert('foo'); }
$('#foo').bind('click', fn);
...
$('#foo').unbind('click', fn);