I would like to know why some people use
element.click();
and others use
element[0].click();
What's the difference?
Thanks
Assuming element is a jQuery object, element.click() triggers a click event on a set of HTML elements that the element consists of. It's the same as calling element.trigger("click")
element[0].click() is invoking the click method on a DOM node (not jQuery object) that is the first in the set that element consists of.
See http://api.jquery.com/click/ (first case)
and https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement.click (second case)
for further reference.
They are very different, so they would be used in different contexts.
One calls click on the first element of an array, the other calls click directly on whatever element is
Related
Lets say I add an element to the dom using jquery, with an onclick handler with a class=“justice” and data-attribute = “1", and then add another element with the same class name, but different data-attribute = “2”, also lets say I gave both elements different values. I should be able to just call $(‘.justice[data-attribute=‘2’]“).val, which would be different than $(‘.justice[data-attribute=‘1’]“).val right?
Yes you should. In your example though, you did not use a period when selecting the class.
Also, do not forget the parentheses following the val call per the jQuery spec.
$(‘justice[data-attribute=‘1’]“).val
VS.
$(".justice[data-attribute='1']").val()
I am trying to understand this particular difference between the direct and delegated event handlers using the jQuery .on() method. Specifically, the last sentence in this paragraph:
When a selector is provided, the event handler is referred to as delegated. The handler is not called when the event occurs directly on the bound element, but only for descendants (inner elements) that match the selector. jQuery bubbles the event from the event target up to the element where the handler is attached (i.e., innermost to outermost element) and runs the handler for any elements along that path matching the selector.
What does it mean by "runs the handler for any elements"? I made a test page to experiment with the concept. But both following constructs lead to the same behavior:
$("div#target span.green").on("click", function() {
alert($(this).attr("class") + " is clicked");
});
or,
$("div#target").on("click", "span.green", function() {
alert($(this).attr("class") + " is clicked");
});
Maybe someone could refer to a different example to clarify this point? Thanks.
Case 1 (direct):
$("div#target span.green").on("click", function() {...});
== Hey! I want every span.green inside div#target to listen up: when you get clicked on, do X.
Case 2 (delegated):
$("div#target").on("click", "span.green", function() {...});
== Hey, div#target! When any of your child elements which are "span.green" get clicked, do X with them.
In other words...
In case 1, each of those spans has been individually given instructions. If new spans get created, they won't have heard the instruction and won't respond to clicks. Each span is directly responsible for its own events.
In case 2, only the container has been given the instruction; it is responsible for noticing clicks on behalf of its child elements. The work of catching events has been delegated. This also means that the instruction will be carried out for child elements that are created in future.
The first way, $("div#target span.green").on(), binds a click handler directly to the span(s) that match the selector at the moment that code is executed. This means if other spans are added later (or have their class changed to match) they have missed out and will not have a click handler. It also means if you later remove the "green" class from one of the spans its click handler will continue to run - jQuery doesn't keep track of how the handler was assigned and check to see if the selector still matches.
The second way, $("div#target").on(), binds a click handler to the div(s) that match (again, this is against those that match at that moment), but when a click occurs somewhere in the div the handler function will only be run if the click occurred not just in the div but in a child element matching the selector in the second parameter to .on(), "span.green". Done this way it doesn't matter when those child spans were created, clicking upon them will still run the handler.
So for a page that isn't dynamically adding or changing its contents you won't notice a difference between the two methods. If you are dynamically adding extra child elements the second syntax means you don't have to worry about assigning click handlers to them because you've already done it once on the parent.
The explanation of N3dst4 is perfect. Based on this, we can assume that all child elements are inside body, therefore we need use only this:
$('body').on('click', '.element', function(){
alert('It works!')
});
It works with direct or delegate event.
Tangential to the OP, but the concept that helped me unravel confusion with this feature is that the bound elements must be parents of the selected elements.
Bound refers to what is left of the .on.
Selected refers to the 2nd argument of .on().
Delegation does not work like .find(), selecting a subset of the bound elements. The selector only applies to strict child elements.
$("span.green").on("click", ...
is very different from
$("span").on("click", ".green", ...
In particular, to gain the advantages #N3dst4 hints at with "elements that are created in future" the bound element must be a permanent parent. Then the selected children can come and go.
EDIT
Checklist of why delegated .on doesn't work
Tricky reasons why $('.bound').on('event', '.selected', some_function) may not work:
Bound element is not permanent. It was created after calling .on()
Selected element is not a proper child of a bound element. It's the same element.
Selected element prevented bubbling of an event to the bound element by calling .stopPropagation().
(Omitting less tricky reasons, such as a misspelled selector.)
I wro te a post with a comparison of direct events and delegated. I compare pure js but it has the same meaning for jquery which only encapsulate it.
Conclusion is that delegated event handling is for dynamic DOM structure where binded elements can be created while user interact with page ( no need again bindings ), and direct event handling is for static DOM elements, when we know that structure will not change.
For more information and full comparison -
http://maciejsikora.com/standard-events-vs-event-delegation/
Using always delegated handlers, which I see is current very trendy is not right way, many programmers use it because "it should be used", but truth is that direct event handlers are better for some situation and the choice which method use should be supported by knowledge of differences.
Case 3 (delegated):
$("div#target").delegate("span.green", "click", function() {...});
This question already has an answer here:
Difference between remove() and detach() in jQuery [closed]
(1 answer)
Closed 10 years ago.
I m not being able to distinguish between the jquery remove() and detach() method as both are acting same or working same ,plz consider the code:
<script>
$(document).ready(function(){
$("#btn1").click(function(){
$("body").append($("#p1").detach());
});
$("#btn2").click(function(){
$("body").append($("#p2").remove());
});
$("p").click(function(){
$(this).animate({fontSize:"+=1px"})
});
});
</script>
From the docs:
The .detach() method is the same as .remove(), except that .detach() keeps all jQuery data associated with the removed elements. This method is useful when removed elements are to be reinserted into the DOM at a later time.
remove() destroys the element completely. detach() removes the element, keeping its data intact.
The detach method doesn't remove interal jQuery data that are associated with the elements (e.g. event bindings), so it's only if there is any such data that you would see any difference.
To move an element from one place to another in the document, you don't have to remove it or detach it, just append it in the new place:
$("body").append($("#p1"));
You're not going to see a visible difference between the two. This excerpt is taken from the jQuery documentation:
The .detach() method is the same as .remove(), except that .detach() keeps all jQuery data associated with the removed elements. This method is useful when removed elements are to be reinserted into the DOM at a later time.
Please review the API documentation on each of these calls:
jQuery Remove
jQuery Detach
As explained by the documentation, $.detach() retains the associated jQuery data whereas $.remove() removes that data. This data contains things like the bound events, the animation queue and whatever you manually added with $.data().
In your original example, you should be able to notice the difference in the following scenario:
Click the paragraph.
Click the button.
Click the paragraph again.
For #p1 and #btn1, clicking the paragraph the second time will still trigger the click handler and bump the font size. This is because the event handler is stored in the data and is retained by detach(). Thus, when reattaching it to the DOM, the handler is still bound.
For #p2 and #btn2 however, the event handler is removed by remove() and clicking on the paragraph the second time won't do anything.
Side note: you don't need to call detach() when you're immediately appending it to the DOM again. detach() may be interesting if you want to store the element in a variable for a while until it needs to be re-appended (with the same data and behaviour). remove() is commonly used to just destroy an element, also cleaning up any associated data.
I am unable to understand why $('#mdiv input')[1].hide(); does not work and at same time why $('#mdiv input')[1].click(); works fine?
Firstly I want to know why? Secondly how to make it working without having the id of the element?
Here is JSFiddle Link to see what i am trying and what I need
That's because you are converting the jQuery object to DOM element object which has no hide method, your second code works as DOM element object has click method like jQuery object. You can use eq method instead which returns a jQuery object.
$('#mdiv input').eq(1).hide();
If you not want to select tags by id, you can use
$('input[name="firstname"]')...
// or
$('input[type="text"][name="firstname"]')...
Is it better to attach the on() event to the document or a closer parent?
Note: Initially this question had another aspect and a different topic. It became obsolete really quickly (typo in the source code)
The best key for performance using jQuery is to use an id as the initial identifier. For example:
$('#my_id').on('click', 'tag.my_class', function () {
...
});
This allows jQuery to go straight to the container, and then begin trawling from there.
if you bind the "on" event to the closest parent will produce exactly what are you looking for, click function will works fine even if it is appended to document, but in future if you append any elements with class "clickable" will also get binded. so its always good practice to append the "on" event to closest parent rather than whole document.
if you want more specific you can use
$("ul.media-grid").on('click', 'li.clickable', function () {
alert("works")
});
as it will get the ul with the class "media-grid" and appends the event to the li's with class "clickable"