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);
Related
I found two great articles talking about the new function .on(): jquery4u.com, elijahmanor.com.
Is there any way where the .bind() still is better to use than .on()?
For example, I have a sample code that look like this:
$("#container").click( function( e ) {} )
You can note that I just have one item retrieved by the selector and in my case, the <div> named #container already exists when my page was loaded; not added dynamically. It’s important to mention that I use the latest version of jQuery: 1.7.2.
For that sample, should .on() be used instead of .bind() even if I don’t use the other features provided by the .on() function?
Internally, .bind maps directly to .on in the current version of jQuery. (The same goes for .live.) So there is a tiny but practically insignificant performance hit if you use .bind instead.
However, .bind may be removed from future versions at any time. There is no reason to keep using .bind and every reason to prefer .on instead.
These snippets all perform exactly the same thing:
element.on('click', function () { ... });
element.bind('click', function () { ... });
element.click(function () { ... });
However, they are very different from these, which all perform the same thing:
element.on('click', 'selector', function () { ... });
element.delegate('click', 'selector', function () { ... });
$('selector').live('click', function () { ... });
The second set of event handlers use event delegation and will work for dynamically added elements. Event handlers that use delegation are also much more performant. The first set will not work for dynamically added elements, and are much worse for performance.
jQuery's on() function does not introduce any new functionality that did not already exist, it is just an attempt to standardize event handling in jQuery (you no longer have to decide between live, bind, or delegate).
The direct methods and .delegate are superior APIs to .on and there is no intention of deprecating them.
The direct methods are preferable because your code will be less stringly typed. You will get immediate error when you mistype an
event name rather than a silent bug. In my opinion, it's also easier to write and read click than on("click"
The .delegate is superior to .on because of the argument's order:
$(elem).delegate( ".selector", {
click: function() {
},
mousemove: function() {
},
mouseup: function() {
},
mousedown: function() {
}
});
You know right away it's delegated because, well, it says delegate. You also instantly see the selector.
With .on it's not immediately clear if it's even delegated and you have to look at the end for the selector:
$(elem).on({
click: function() {
},
mousemove: function() {
},
mouseup: function() {
},
mousedown: function() {
}
}, "selector" );
Now, the naming of .bind is really terrible and is at face value worse than .on. But .delegate cannot do non-delegated events and there
are events that don't have a direct method, so in a rare case like this it could be used but only because you want to make a clean separation between delegated and non-delegated events.
If you look in the source code for $.fn.bind you will find that it's just an rewrite function for on:
function (types, data, fn) {
return this.on(types, null, data, fn);
}
http://james.padolsey.com/jquery/#v=1.7.2&fn=$.fn.bind
From the jQuery documentation:
As of jQuery 1.7, the .on() method is the preferred method for attaching event handlers to a document. For earlier versions, the .bind() method is used for attaching an event handler directly to elements. Handlers are attached to the currently selected elements in the jQuery object, so those elements must exist at the point the call to .bind() occurs. For more flexible event binding, see the discussion of event delegation in .on() or .delegate().
http://api.jquery.com/bind/
As of Jquery 3.0 and above .bind has been deprecated and they prefer using .on instead. As #Blazemonger answered earlier that it may be removed and its for sure that it will be removed. For the older versions .bind would also call .on internally and there is no difference between them. Please also see the api for more detail.
jQuery API documentation for .bind()
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);
});
I am trying to use the on method for future DOM elements, but for some reason instead of calling events on click, it fires them when the DOM objects are dynamically created.
here's the code that I have.
$("#checkbox1").on('click', toggleChecked(this.checked)); //this is included in Ajax call success method
function toggleChecked(status) {
$(".item").each(function () {
$(this).prop("checked", status);
});
}
What am I doing wrong here?
toggleChecked(this.checked) will right away execute the function and then on will get its return value as handler which is undefined.
Wrap it an anonymous function so that it will be called when you click on the checkbox.
$("#checkbox1").on('click', function(){
toggleChecked(this.checked)
});
If you use toggelChecked method directy as click handler you can get the checked status of the checkbox using `this.checked inside the handler.
Two problems:
By adding parenthesis, you are executing the function, you have to pass a reference to the function to .on()
You cannot pass parameters like you want to do. But this in the event handler will be the clicked DOMElement, so you can get the checked property value inside it with this.checked
Here's a modified code:
$("#checkbox1").on('click', toggleChecked);
function toggleChecked() {
// "this" here is the clicked element
var status = this.checked;
$(".item").each(function () {
// be careful in .each() 'this' is the currently iterated element
$(this).prop("checked", status);
});
}
You have to put the event listener within function literals. Otherwise, the function is directly called.
$("#checkbox1").on('click', function() {
toggleChecked(this.checked);
});
The function itself can be written more efficiently:
function toggleChecked(status) {
$(".item").prop("checked", status);
}
As people have pointed out, you are doing the function wrong (the function has to be an anonymous function or a pointer to a function, or string that points to a function). But you are also using 'on' method wrong, it is not exactly the same as the 'live' method. You watch the document (or an area of the document), and have a subselector in that.
$(document).on('click', "#checkbox1", function() {
var status = this.checked;
$(".item").each(function () {
$(this).prop("checked", status);
});
Note: If all your checkboxes are getting created in the 'checkBoxDiv' your selector can be:
$("#checkBoxDiv").on('click', "#checkbox1", ...
For more information about how to use 'on' see the comparison in functions in the 'live' documentation (about 1/3 of the way down the page).
From the documentation:
Rewriting the .live() method in terms of its successors is
straightforward; these are templates for equivalent calls for all
three event attachment methods:
$(selector).live(events, data, handler); // jQuery 1.3+
$(document).delegate(selector, events, data, handler); // jQuery
1.4.3+ $(document).on(events, selector, data, handler); // jQuery 1.7+
The events argument can either be a space-separated list of event type
names and optional namespaces, or an event-map of event names strings
and handlers. The data argument is optional and can be omitted. For
example, the following three method calls are functionally equivalent
(but see below for more effective and performant ways to attach
delegated event handlers):
$("a.offsite").live("click", function(){ alert("Goodbye!"); }); // jQuery 1.3+
$(document).delegate("a.offsite", "click", function(){ alert("Goodbye!"); }); // jQuery 1.4.3+
$(document).on("click", "a.offsite", function(){ alert("Goodbye!"); }); // jQuery 1.7+