jquery use of bind vs on click - javascript

I have come across several methods for handling click events in jquery:
bind:
$('#mydiv').bind('click', function() {
...
});
click:
$('#mydiv').click(function() {
...
}
on:
$('mydiv').on('click', function() {
...
}
Two questions:
Are they any other ways of doing this?
Which one should I use, and why ?
UPDATE:
As eveyone has helpfully suggested, I should have read the docs better, and found out that I should use:
on() or click(),
which are effectively the same thing.
However, nobody has explained why bind is no longer recommended ? I'll probably get more downvotes for missing the obvious somewhere, but I can't find a reason for this in the documents.
UPDATE2:
'on' has the useful effect of being able to add event handlers to dynamically created elements. e.g.
$('body').on('click',".myclass",function() {
alert("Clicked On MyClass element");
});
This code adds a click handler to elements with a class of 'myClass'. However, if more myClass elements are then dynamically added later, they automatically get the click handler as well, without having to explicitly call 'on'. From what I understand people are saying, this is also more efficient (see Simons answer below).

From the documentation of bind and click :
bind :
As of jQuery 1.7, the .on() method is the preferred method for
attaching event handlers to a document.
The source makes it clear there's no reason to use bind, as this function only calls the more flexible on function without even being shorter :
bind: function( types, data, fn ) {
return this.on( types, null, data, fn );
},
So I'd suggest, just like the jQuery team, to forget the old bind function, which is now useless. It's only for compatibility with older code that it's still here.
click :
This method is a shortcut for .on('click', handler)
This shortcut is of course less powerful and flexible than the on function and doesn't allow delegation but it lets you write a shorter and, arguably, slightly more readable, code when it applies. Opinions diverge on that point : some developers argue that it should be avoided as it is just a shortcut, and there's also the fact that you need to replace it with on as soon as you use delegation, so why not directly use on to be more consistent ?

To your first question: there's also .delegate, which was superseded by .on as of jQuery 1.7, but still is a valid form of binding event handlers.
To your second question: You should always use .on like the docs say, but you should also pay attention on how to use .on, because you can either bind the event handler on an object itself or a higher level element and delegate it like with .delegate.
Say you have an ul > li list and want to bind a mouseover event to the lis. Now there are two ways:
$('ul li').on('mouseover', function() {});
$('ul').on('mouseover', 'li', function() {});
The second one is preferable, because with this one the event handler gets bound to the ul element once and jQuery will get the actual target item via event.currentTarget (jQuery API), while in the first example you bind it to every single list element. This solution would also work for list items that are being added to the DOM during runtime.
This doesn't just work for parent > child elements. If you have a click handler for every anchor on the page you should rather use $(document.body).on('click', 'a', function() {}); instead of just $('a').on('click', function() {}); to save a lot of time attaching event handlers to every element.

I think that you should have searched the jquery docs before posting this question :
As of jQuery 1.7, the .on() method is the preferred method for attaching event handlers to a document.

Related

preventing an inline script from running [duplicate]

I have an input type="image". This acts like the cell notes in Microsoft Excel. If someone enters a number into the text box that this input-image is paired with, I setup an event handler for the input-image. Then when the user clicks the image, they get a little popup to add some notes to the data.
My problem is that when a user enters a zero into the text box, I need to disable the input-image's event handler. I have tried the following, but to no avail.
$('#myimage').click(function { return false; });
jQuery ≥ 1.7
With jQuery 1.7 onward the event API has been updated, .bind()/.unbind() are still available for backwards compatibility, but the preferred method is using the on()/off() functions. The below would now be,
$('#myimage').click(function() { return false; }); // Adds another click event
$('#myimage').off('click');
$('#myimage').on('click.mynamespace', function() { /* Do stuff */ });
$('#myimage').off('click.mynamespace');
jQuery < 1.7
In your example code you are simply adding another click event to the image, not overriding the previous one:
$('#myimage').click(function() { return false; }); // Adds another click event
Both click events will then get fired.
As people have said you can use unbind to remove all click events:
$('#myimage').unbind('click');
If you want to add a single event and then remove it (without removing any others that might have been added) then you can use event namespacing:
$('#myimage').bind('click.mynamespace', function() { /* Do stuff */ });
and to remove just your event:
$('#myimage').unbind('click.mynamespace');
This wasn't available when this question was answered, but you can also use the live() method to enable/disable events.
$('#myimage:not(.disabled)').live('click', myclickevent);
$('#mydisablebutton').click( function () { $('#myimage').addClass('disabled'); });
What will happen with this code is that when you click #mydisablebutton, it will add the class disabled to the #myimage element. This will make it so that the selector no longer matches the element and the event will not be fired until the 'disabled' class is removed making the .live() selector valid again.
This has other benefits by adding styling based on that class as well.
This can be done by using the unbind function.
$('#myimage').unbind('click');
You can add multiple event handlers to the same object and event in jquery. This means adding a new one doesn't replace the old ones.
There are several strategies for changing event handlers, such as event namespaces. There are some pages about this in the online docs.
Look at this question (that's how I learned of unbind). There is some useful description of these strategies in the answers.
How to read bound hover callback functions in jquery
If you want to respond to an event just one time, the following syntax should be really helpful:
$('.myLink').bind('click', function() {
//do some things
$(this).unbind('click', arguments.callee); //unbind *just this handler*
});
Using arguments.callee, we can ensure that the one specific anonymous-function handler is removed, and thus, have a single time handler for a given event. Hope this helps others.
maybe the unbind method will work for you
$("#myimage").unbind("click");
I had to set the event to null using the prop and the attr. I couldn't do it with one or the other. I also could not get .unbind to work. I am working on a TD element.
.prop("onclick", null).attr("onclick", null)
If event is attached this way, and the target is to be unattached:
$('#container').on('click','span',function(eo){
alert(1);
$(this).off(); //seams easy, but does not work
$('#container').off('click','span'); //clears click event for every span
$(this).on("click",function(){return false;}); //this works.
});​
You may be adding the onclick handler as inline markup:
<input id="addreport" type="button" value="Add New Report" onclick="openAdd()" />
If so, the jquery .off() or .unbind() won't work. You need to add the original event handler in jquery as well:
$("#addreport").on("click", "", function (e) {
openAdd();
});
Then the jquery has a reference to the event handler and can remove it:
$("#addreport").off("click")
VoidKing mentions this a little more obliquely in a comment above.
If you use $(document).on() to add a listener to a dynamically created element then you may have to use the following to remove it:
// add the listener
$(document).on('click','.element',function(){
// stuff
});
// remove the listener
$(document).off("click", ".element");
To remove ALL event-handlers, this is what worked for me:
To remove all event handlers mean to have the plain HTML structure without all the event handlers attached to the element and its child nodes. To do this, jQuery's clone() helped.
var original, clone;
// element with id my-div and its child nodes have some event-handlers
original = $('#my-div');
clone = original.clone();
//
original.replaceWith(clone);
With this, we'll have the clone in place of the original with no event-handlers on it.
Good Luck...
Updated for 2014
Using the latest version of jQuery, you're now able to unbind all events on a namespace by simply doing $( "#foo" ).off( ".myNamespace" );
Best way to remove inline onclick event is $(element).prop('onclick', null);
Thanks for the information. very helpful i used it for locking page interaction while in edit mode by another user. I used it in conjunction with ajaxComplete. Not necesarily the same behavior but somewhat similar.
function userPageLock(){
$("body").bind("ajaxComplete.lockpage", function(){
$("body").unbind("ajaxComplete.lockpage");
executePageLock();
});
};
function executePageLock(){
//do something
}
In case .on() method was previously used with particular selector, like in the following example:
$('body').on('click', '.dynamicTarget', function () {
// Code goes here
});
Both unbind() and .off() methods are not going to work.
However, .undelegate() method could be used to completely remove handler from the event for all elements which match the current selector:
$("body").undelegate(".dynamicTarget", "click")
I know this comes in late, but why not use plain JS to remove the event?
var myElement = document.getElementById("your_ID");
myElement.onclick = null;
or, if you use a named function as an event handler:
function eh(event){...}
var myElement = document.getElementById("your_ID");
myElement.addEventListener("click",eh); // add event handler
myElement.removeEventListener("click",eh); //remove it
This also works fine .Simple and easy.see http://jsfiddle.net/uZc8w/570/
$('#myimage').removeAttr("click");
if you set the onclick via html you need to removeAttr ($(this).removeAttr('onclick'))
if you set it via jquery (as the after the first click in my examples above) then you need to unbind($(this).unbind('click'))
All the approaches described did not work for me because I was adding the click event with on() to the document where the element was created at run-time:
$(document).on("click", ".button", function() {
doSomething();
});
My workaround:
As I could not unbind the ".button" class I just assigned another class to the button that had the same CSS styles. By doing so the live/on-event-handler ignored the click finally:
// prevent another click on the button by assigning another class
$(".button").attr("class","buttonOff");
Hope that helps.
Hope my below code explains all.
HTML:
(function($){
$("#btn_add").on("click",function(){
$("#btn_click").on("click",added_handler);
alert("Added new handler to button 1");
});
$("#btn_remove").on("click",function(){
$("#btn_click").off("click",added_handler);
alert("Removed new handler to button 1");
});
function fixed_handler(){
alert("Fixed handler");
}
function added_handler(){
alert("new handler");
}
$("#btn_click").on("click",fixed_handler);
$("#btn_fixed").on("click",fixed_handler);
})(jQuery);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="btn_click">Button 1</button>
<button id="btn_add">Add Handler</button>
<button id="btn_remove">Remove Handler</button>
<button id="btn_fixed">Fixed Handler</button>
I had an interesting case relevant to this come up at work today where there was a scroll event handler for $(window).
// TO ELIMINATE THE RE-SELECTION AND
// RE-CREATION OF THE SAME OBJECT REDUNDANTLY IN THE FOLLOWING SNIPPETS
let $window = $(window);
$window.on('scroll', function() { .... });
But, to revoke that event handler, we can't just use
$window.off('scroll');
because there are likely other scroll event handlers on this very common target, and I'm not interested in hosing that other functionality (known or unknown) by turning off all of the scroll handlers.
My solution was to first abstract the handler functionality into a named function, and use that in the event listener setup.
function handleScrollingForXYZ() { ...... }
$window.on('scroll', handleScrollingForXYZ);
And then, conditionally, when we need to revoke that, I did this:
$window.off('scroll', $window, handleScrollingForXYZ);
The janky part is the 2nd parameter, which is redundantly selecting the original selector. But, the jquery documentation for .off() only provides one method signature for specifying the handler to remove, which requires this middle parameter to be
A selector which should match the one originally passed to .on() when attaching event handlers.
I haven't ventured to test it out with a null or '' as the 2nd parameter, but perhaps the redundant $window isn't necessary.

Idiomatic way to set property to function value using jQuery

To hopefully head off the "primarily-opinion-based" close-button-clickers, I'm not looking for opinions on the "best" way to do this; I'm just wondering if there is a more straightforward solution that I'm missing.
My goal is to add the same onclick method to all of the (hundreds of) checkboxes on my page. My first attempt at a jQuery solution was this:
$('input[type="checkbox"]').prop('onclick', function(){alert("Boop!");})
But that runs into the computed-value behavior of $.prop() and calls the function immediately for each checkbox.
So I can do this:
$('input[type="checkbox"]').prop('onclick', function(){return function() {alert("Boop!");}})
But that feels awfully workaround-y. Alternatively, I could do this:
$('input[type="checkbox"]').each(function(_, cb) {
cb.onclick = function(){alert("Boop!");};
});
But that seems uncharacteristically manual for jQuery.
So am I missing a more straightforward solution?
Declare the function and then simply refer to it by name:
function handler() { alert("Boop!"); }
$("input[type='checkbox']").on("click", handler);
Note that you shouldn't be setting up event handlers by setting the "onfoo" properties.
edit — if what you want to avoid is adding the handler over and over again, use delegation:
$("body").on("click", "input:checkbox", handler);
That creates only one event handler registration. As "click" events bubble up the DOM to the body, jQuery will check to see which ones targeted elements that match the selector, and invoke your handler for those that do. (Opinion — I've mostly adopted the practice of exclusively using body-level delegation for all events. It makes things a lot less messy.)
you have to write event no use prop:
$('input:checkbox').on('click', function(){alert("Boop!");})
i will suggest to use change event for checkbox not click:
$('input:checkbox').on('change', function(){
if(this.checked)
{
alert("checked");
}
});

Efficient way of binding events to element in jQuery

I have one anchor element in my page
Click
I know in jQuery we have so many ways of binding events to element like (bind, live, delegate, on).
FYI:
http://blog.tivix.com/2012/06/29/jquery-event-binding-methods/
Currently using jquery1.8.3.min.js. I want to know which one is standard and efficient event registration model in jQuery?
Currently I am doing it like this:
$("#page").click(function(){
................................
});
Can I change to bind like below code:
$("#page").bind("click",clickFunc);
function clickFunc()
{
..........
}
Which one is best practice to register the event in jQuery 1.8 ?
The best way is the way one can understand what's written and the one that works.
The smart way is to use what's suggested to use, in this case the .on() method:
The .on() method attaches event handlers to the currently selected set of elements in the jQuery object. As of jQuery 1.7, the .on() method provides all functionality required for attaching event handlers. For help in converting from older jQuery event methods, see .bind(), .delegate(), and .live(). To remove events bound with .on(), see .off(). To attach an event that runs only once and then removes itself, see .one()
The how-to way depends if you need to delegate your event/s to dynamically generated elements or not.
$('.child').on( 'click', function() { /* ... */ });
$('#parent').on( 'click', ".dyn-gen-child", function() { /* ... */ });
.on is the standard method:
$("#page").on("click", function() {
.......
});
If the p element is generated dynamically, you'll have to do:
$(document).on("click", "#page", function() {
.......
});
Actually, after jQuery 1.7, on is the preferred way to bind events rather than bind. So I prefer on API.
And then:
click(function(){})
is just the shortcut of
on('click',function(){})
Internally, they are actually the same -- when the on param is event, handler, but on is more general because it can do more than simple onClick(example:event delegation) see:link
so I recommend on

Is there an advantage to using jQuery's $().on('mouseenter',function(){}) over $().mouseenter(function(){})?

I frequently see code like:
$("#thing").on("mouseenter",function(){ Do stuff });
Personally, I almost always write:
$("#thing").mouseenter(function(){ Do stuff });
Similarly, I often write
$("#thing").click(function(){})
but I have seen people correct it to (yes, I know on is preferred over bind in v. 1.7+, so it's essentially the same preference issue):
$("#thing").bind("click",function(){})
Am I doing something "wrong", is there a deep difference between the two functions that I'm not seeing? It always seems to do what I want it to do, so it's never been a practical concern, but I'd be interested to know if there's a theoretical consideration I'm overlooking.
Not really, it's just a little faster as the mouseenter function calls on (or trigger if called without argument) as can be seen in the source code :
jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
"change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) {
// Handle event binding
jQuery.fn[ name ] = function( data, fn ) {
return arguments.length > 0 ?
this.on( name, null, data, fn ) :
this.trigger( name );
};
});
As you can see, the same can be said for many events.
Personally, I prefer to use the mouseenter (or click, etc.) function when I don't need the special features of on : one of the big advantages in my opinion in using jQuery is that it makes the code less verbose and more readable. And I don't think you should be corrected, ask the guys who corrects you why he does that.
Normally, the specific events like .click or $.post are shortcuts. They act the same as using the .on and $.ajax functions but the latter normally have greater flexibility. EG .on can bind to multiple event while .click only subscribes to clicks. Same applies to the $.ajax function, there are more options where as the shortcuts have certain defaults set.
There's no practical difference between the two, the shorthand functions (.click(), .mouseover(), etc) call .on() to actually bind the event handler anyway. The only "advantage" to using .on() directly is that you don't have the additional overhead of a second function call; I suspect that's likely to be marginal enough that it's a very premature optimisation though.
It's not neccessarily wrong, but on has its advantages over the normal way.
By "binding" the event to your parent container $(parent).on(event, target, function() { //foobar }); you are able to add new target elements into your container, while not having to repeat the jquery to bind the event.

jQuery - Calling .trigger('click') vs .click()

In jQuery what is the better way to trigger an event such as click? Using the .trigger('click') function or calling .click()?
I have always triggered this event by using .click() but suddenly decided maybe I should be using .trigger('click') instead.
I use these event triggers to trigger event listeners created with .on('click', function(){...}).
I have checked the jquery api, searched other stackoverflow posts [ 1 ] [ 2 ] and I can see no reason to use one over the other.
I would be more inclined to use .trigger() to keep all event triggering consistent, as this can be used to call any event including custom events. But it would seem .trigger() does not work in all cases.
What is the best way to trigger an event? .trigger('click') or .click()?
If you're using .trigger() you have the advantage of being able to pass additional parameters, whereas .click() must be called without any.
Taken from the documentation:
$('#foo').bind('custom', function(event, param1, param2) {
alert(param1 + "\n" + param2);
});
$('#foo').trigger('custom', ['Custom', 'Event']);
'Custom' and 'Event' are being passed to the event handler as param1 and param2 respectively
Besides that, the .click() is unlike other functions that implement get / set based on the number of arguments, because it implements trigger / set instead. Using a dedicated .trigger(), to me, is more logical.
One caveat to be aware of when using the jQuery method is that, in addition to being a jQuery method, .click() is also a DOM Level 2 native JavaScript method that can be called on HTML elements, such as <button> elements.
One place where this can become confusing is if you have a selector like this:
$("#element")[0].click();
There, you are actually calling the method on the DOM element. For instance, if you tried
$("#element")[0].trigger('click');
you would get an error that the element has no trigger method defined.
Be aware that $('#element')[0].click(); won't work in Safari, on certain elements. You will need to use a workaround.

Categories

Resources