I'm working on creating a more accessible navigation, and in particular want to use determine whether a keypress is used. While I want to figure out why this is not working for me, I also want to know the difference between several methods that do the same thing. Those methods are:
$('ul li a').on('keypress', function(e){...});
& $('ul li a').keypress(function(e) {...});
& $('ul li a').bind('keypress', function(e) {...});
What is the difference if any? And is there a 'right' one to use for this siutation? Either way, none of them are actually working for me. I have setup console logs throughout the script I have written and while the console is logging the script loading, it detects the keydown, however it does not detect the return key being pressed, the whole script looks like:
$('ul li a').on('keypress', function(e){
if(e.keyCode==13){ // return / enter key
console.log("Return Key Pressed");
}
return false;
});
Thanks!
** EDIT **
I never discovered why the return key (or down arrow) was not working, neither would trigger the keydown event in the console, but I did discover the spacebar is the best method for accessibility, the end result looked like:
$('ul li a').on('keypress', function(e){
if ((e.keyCode || e.which) == 32) { // spacebar
... script ...
return false;
}
});
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.
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);
}
For keypress function, i don't recommend it because it work only for exsiting elements ; if element will be exist after running keypress , it will not handle new elements.
Instead you can use delegate :
$(document).delegate('ul li a','keypress',function(event){
//........
})
.on() is the preferred way to do all events in jQuery 1.7+
As of jQuery 1.7, the .on() method provides all functionality required
for attaching event handlers.
From the official docs: http://api.jquery.com/on/
Other methods of attaching events appear to be deprecated:
For help in converting from older jQuery event methods, see .bind(),
.delegate(), and .live().
Related
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");
}
});
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Closed 9 years ago.
Improve this question
I am having trouble with the jquery, at the moment using v2.1, the problem is that it is firing the below twice!
I cant get this work, don't know why this is happening :(
$(document).on('click', '#task-list li.listing', function(e){
e.preventDefault();
e.stopPropagation();
alert("hello!");
$(".hiddentaskedit").show();
$(".lefthelp1").hide();
$("#task-list>li.list-group-item").removeClass("active");
$(this).addClass("active");
$("#listsbtfrm")[0].reset();
$("#datatextchk").focus();
var a = $(this).children(".view").children(".checkbox").children(".task-name1").html();
var b = $(this).children(".view").children(".checkbox").children(".task-name2").html();
var c = $(this).children(".view").children(".checkbox").children(".task-name3").html();
if(a.length>0){ $("#datatextchk").val(a); }
if(b.length>0){ $("#datatextchk2").val(b); }
if(c.length>0){ $("#datatextchk3").val(c); }
return false;
});
wv
That's because of having e.stopPropagation(); after e.preventDefault();. Try using e.preventDefault(); after e.stopPropagation();.
Since e.stopPropagation(); stops the flow to relative elements where as e.preventDefault(); stops natural flow, in other words,
e.stopPropagation(); stops the event from bubbling up the event chain.
e.preventDefault(); prevents the default action the browser makes on that event.
$(document).on('click', '#task-list li.listing', function(e){
alert("hello!");
$(".hiddentaskedit").show();
$(".lefthelp1").hide();
$("#task-list>li.list-group-item").removeClass("active");
$(this).addClass("active");
$("#listsbtfrm")[0].reset();
$("#datatextchk").focus();
var a = $(this).children(".view").children(".checkbox").children(".task-name1").html();
var b = $(this).children(".view").children(".checkbox").children(".task-name2").html();
var c = $(this).children(".view").children(".checkbox").children(".task-name3").html();
if(a.length>0){ $("#datatextchk").val(a); }
if(b.length>0){ $("#datatextchk2").val(b); }
if(c.length>0){ $("#datatextchk3").val(c); }
e.stopPropagation();
e.preventDefault();
return false;
});
If it still does not work remove e.preventDefault(); from the code i.e. =>
$(document).on('click', '#task-list li.listing', function(e){
alert("hello!");
$(".hiddentaskedit").show();
$(".lefthelp1").hide();
$("#task-list>li.list-group-item").removeClass("active");
$(this).addClass("active");
$("#listsbtfrm")[0].reset();
$("#datatextchk").focus();
var a = $(this).children(".view").children(".checkbox").children(".task-name1").html();
var b = $(this).children(".view").children(".checkbox").children(".task-name2").html();
var c = $(this).children(".view").children(".checkbox").children(".task-name3").html();
if(a.length>0){ $("#datatextchk").val(a); }
if(b.length>0){ $("#datatextchk2").val(b); }
if(c.length>0){ $("#datatextchk3").val(c); }
e.stopPropagation();
return false;
});
I have written the both functions at bottom of function as it supports other browsers(in my experiment of using it above, my function was breaking).
Update
1. As you want for dynamic (and you did not mention that before), you'll have to use live event instead of on
change this $(document).on('click', '#task-list li.listing', function(e){
to $( selector ).live( events, data, handler ){ // jQuery 1.3+
or
As suggested by AbdulJabbarWebBestow live is depreciated, either way you can use delegate
$( document ).delegate( '#task-list li.listing', "click", function(e) { // jQuery 1.4.3+
2. *More details* (source http://api.jquery.com/live/ )
jQuery attempts to retrieve the elements specified by the selector before calling the .live() method, which may be time-consuming on large documents.
Chaining methods is not supported. For example, $( "a" ).find( ".offsite, .external" ).live( ... ); is not valid and does not work as expected.
Since all .live() events are attached at the document element, events take the longest and slowest possible path before they are handled.
On mobile iOS (iPhone, iPad and iPod Touch) the click event does not bubble to the document body for most elements and cannot be used with .live() without applying one of the following workarounds:
Use natively clickable elements such as a or button, as both of these do bubble to document.
Use .on() or .delegate() attached to an element below the level of document.body, since mobile iOS does bubble within the body.
Apply the CSS style cursor:pointer to the element that needs to bubble clicks (or a parent including document.documentElement). Note however, this will disable copy\paste on the element and cause it to be highlighted when touched.
Calling event.stopPropagation() in the event handler is ineffective in stopping event handlers attached lower in the document; the event has already propagated to document.
The .live() method interacts with other event methods in ways that can be surprising, e.g., $( document ).off( "click" ) removes all click handlers attached by any call to .live()!
For pages still using .live(), this list of version-specific differences may be helpful:
Before jQuery 1.7, to stop further handlers from executing after one bound using .live(), the handler must return false.
Calling .stopPropagation() will not accomplish this.
As of jQuery 1.4 the .live() method supports custom events as well as all JavaScript events that bubble.
It also supports certain events that don't bubble, including change, submit, focus and blur.
In jQuery 1.3.x only the following JavaScript events could be bound: click, dblclick, keydown, keypress, keyup, mousedown, mousemove, mouseout, mouseover, and mouseup.
3. As you commented on AbdulJabbarWebBestow ,
The second one is working in which we called the variable to check
"true/false" but I have lots of "click" functions do I have to use
this in every 1 of them? Is there any other universal method :) Also I
will be clicking few classes and this will not work on them ! –
Ans= Better give common class name to all of your required html elements, that you want to handle and use id for unique identification. Try using this inside function of the event, example this.id would return the id of that class name. This method is standard way for handling dynamic elements and so called universal :) .
I hope this helped you.
Please let me know for further doubts/clarification.
Try this, it is working good
$(document).unbind('click').on('click', '#task-list li.listing', function(e)
{
alert('Hellow world');
e.stopPropagation();
return false;
});
And it's definitely Javascript problem because if you hit google and search for event fire twice you will see that Angular, Jquery and backbone etc all are somewhere firing events twice or even thrice. So, it's seem that it's javascript behind this.
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
So i have some data on a page (a table) which based on some options elsewhere may get ajax reloaded from the server.
This table has buttons in it that can be clicked to make other things happen to the records in the table.
I notice that this ...
http://api.jquery.com/on/
... is the recommended approach for attaching simple event handlers to elements but that only attaches to elements that exist right now, and when I do my ajax load I lose the attached handlers.
So I started using this ... http://api.jquery.com/live/ ... and guess what, jquery team did their usual and deprecated it saying I should be using "on".
These functions behave very differently yet jquery docs say i should be using them interchangably so ...
Can someone explain the "on" equivelent of this and how I can get it to work with elements after an ajax call replacing the elements that hae previously been attached to ...
$("some selector").live('click', function (e) {
// some code code
e.preventDefault();
return false;
});
My understanding is that you would do something like ...
$("some selector").on('click', function (e) {
// some code code
e.preventDefault();
return false;
});
My guess is that I then have to re-run this code after performing my ajax call by putting this in to some sort of "initClicks" function and calling it both on page load and after the ajax call.
This seems to be a bit of a back step to me ... or have i missed something here?
Since the elements are added dynamically, you need to use event delegation to register the event handler
// New way (jQuery 1.7+) - .on(events, selector, handler)
$(document).on('click', 'some selector', function(event) {
// some code code
e.preventDefault();
return false;
});
Also, either use e.preventDefault() or return false, as:
return false = e.preventDefault() + e.stopPropagation()
So, there is no need to use both of them at same time.
When you use .on('click', function (e) {}) function, it works only for existing elements.
To handle click event on all selector elements, even for elements which will be added in future, you can use one of these functions:
$(document).on('click', "some selector", function (e) {
// some code code
e.preventDefault();
return false;
});
or:
$("body").delegate("a", "click", function () {
// your code goes here
});
For more information read article about Understanding Event Delegation
live() is not magic, it cannot see future elements, what it was doing is to attach a listener to the first root element of your page document and checks every bubbled event if it match your target selector, and when it find a match, it executes your function.
this is called event delegation
live() has been deprecated for good reasons, mainly the performance hit caused by using it.
then the jQUery team introduced the delegate() function which gave us a new way to achieve the exact result, but it has addressed the performance hit very cleverly by limiting the scope in which it will listen to bubbled events to the possible nearest parent of your now & future elements.
when they introduced the On() function, they gave you the ability to use it as normal event handler, or as a delegated handler for future elements.
so I believe they did a good job for this, giving us the flexibility to use it as we wish according to the specific scenario.
Code Examples:
using delegate():
$( "#TAGERT_ID" ).delegate( "a", "click", function() { // your code goes here}
using on() (for delegated events)
$( "#TAGERT_ID" ).on( "click", "a", function() { // your code goes here}
both ways are the same, and will handle future clicks on a which will be added in the future inside your TARGET_ID element.
TARGET_ID is an example for using ID for your selector, but you can use whatever selector according to your specific need.
The equivalent of said live is
$(document).on('click', "some selector", function (e) {
// some code code
e.preventDefault();
return false;
});
The on() is a single stop for all event handler formats, the model you used is the same as
$("some selector").click(function (e) {
// some code code
e.preventDefault();
return false;
});
which does work based event delegation.
You can never actually attach event listener to an element which does not exist in DOM yet. What live and on method do is attach listener on a parent which exists right now. live is nothing but an on attached on document itself.
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.