When Using Jquery On(), Why Use (Document) VS. the Element Itself

When using jQuery on(), why use (document) vs. the element itself?

Both of those are valid.

The former works for dynamically added elements. You use document because you're delegating events on children of the document object, so events bubble up to the document level. It's also more convenient to select the closest parent you can (and the parent must exist on the page at load).

The latter still works, and is a preferred way to simply bind events to specific elements.

I personally don't recommend delegating through the document object, but rather the closest parent that exists on page load.

Here are the docs for on().

What is different between $(document).on() and $(element).on()

Main difference is already answered by @Mukesh.
I will try to add one more thing.

When you click(or any other event) on an element(like div or button) in the html document, that clicking event is propagated to the parent elements of that element. So if you have structure like this:

<div>
<table>
<tr>
<td>
<button>Click Me</button>
</td>
</tr>
</table>
</dvi>

and you click on the button, that click will propagate to the td, then to the tr, then to the table and then finally to the document itself.

Now lets say you have registered a click event on the document($document.on('click',...)) and also on the button($(button.on('click',...))), both of which does some different actions. Then if you click on the button, the corresponding button action will be executed, and also the corresponding action of the $(document) will also be executed.

To prevent the button click to propagate to the document itself, you need to take actions on the button click handler(like stopPropagation etc.)

$(document) vs. $(document)

$(document) uses jQuery to wrap the global document object.

$("document") attempts to look for a <document> element, which obviously makes no sense in HTML because there's no such element, only a root document object represented in the markup by the <html> element. It behaves that way because by passing the jQuery function a string, you're actually giving it a selector.

Re edit: as patrick dw says, in the context of ready() there's no difference, and in fact as of jQuery 3.0 using $(document) at all or explicitly calling ready() is deprecated. From the documentation:

jQuery offers several ways to attach a function that will run when the DOM is ready. All of the following syntaxes are equivalent:

  • $( handler )
  • $( document ).ready( handler )
  • $( "document" ).ready( handler )
  • $( "img" ).ready( handler )
  • $().ready( handler )

As of jQuery 3.0, only the first syntax is recommended; the other syntaxes still work but are deprecated. This is because the selection has no bearing on the behavior of the .ready() method, which is inefficient and can lead to incorrect assumptions about the method's behavior. For example, the third syntax works with "document" which selects nothing. The fourth syntax waits for the document to be ready but implies (incorrectly) that it waits for images to become ready.

jquery: on vs live

.on combines and replaces .bind, .live, and .delegate. The syntax $('selector').on('event', callback) is the moral equivalent of bind, not live.

Add a filtering selector to your call to on:

$('container').on('click', 'child-filter', callback);

In this case,

$('.a').on("click", ".alert-link", function(){
alert('abc');
return false;
});

This was changed because it is more efficient to attach a delegate handler to a more localized container element than the old .live style of attaching the handler to the root of the DOM.

In other words, even though alert-link elements will only appear inside of a small a div, with .live, jQuery listens to every single click event on the page and compares it to the delegated selector. By being more targeted, jQuery only has to process clicks on elements within a.

How does jQuery's new on() method compare to the live() method in performance?

As I understand .live() and .on(), the two examples you have included do not so the same thing.

Your first one:

$('#some-button').on('click', function() {
//do something when #some-button is clicked
});

does not have a live behavior. It finds the #some-button object and installs an event handler on it directly. This is very efficient, but does not have .live() behavior. If the #some-button object does not exist at this time, no event handler will be installed ever. It is basically the same as this:

$('#some-button').click(function() {
//do something when #some-button is clicked
});

Your second one:

$('#some-button').live('click', function() {
//do something when #some-button is clicked
});

has live behavior. It installs an event handler on the document and waits for clicks targeted to an object that matches "#some-button" to bubble up to the document object. Your second one is theoretically equivalent to this:

$(document).on('click', '#some-button', function() {
//do something when #some-button is clicked
});

I say theoretically equivalent because it should install the same event handlers, but I don't know if the jQuery code for processing the two is identical or not.

One of the reasons that .live() has been deprecated is that it can be a bad thing to have a lot of .live() handlers because you get a lot of event handlers on the document object. Then, every click or even mousemove that bubbles up to the document object has to be checked against a LOT of selectors which can really slow things down.

Another issue with .live() is that it evaluates the selector "#some-button" at the time you make the call, but doesn't actually use that result so it's wasteful. The .on() version doesn't evaluate the selector passed as an argument to .on() when you make the first call because it isn't needed at that time - it's only need later when an actual click comes in that has to be compared to the selector.

With the advent of .on() (or something you could previously do with .delegate()), you can target your "live" event handlers more efficiently by not putting them all on the document object, but rather putting them on a parent object that does not come and go and is a lot closer to where the real objects are such as this:

$('#some-button-parent').on('click', '#some-button', function() {
//do something when #some-button is clicked ///////
});

This spreads the event handlers out to different objects and gets them closer to the actual objects for which they are meant meaning you don't end up with this giant list of event handlers that have to be checked against selectors on every mousemove or click event. That's why .live() has been replaced and deprecated. It's much better to use .delegate() or .on() and specify a parent object that isn't as far away as the document object.

The advantage of the new .on() syntax is that you can do both "live" and "static" event handlers with the same method now, just by varying how you pass the arguments. The jQuery object is where the event handler will be installed and the optional selector in the second argument is a selector that the event target must match. If you pass that selector, then all events hitting the object(s) specified in the jQuery object will have their target checked against that selector. If there is no selector, then only objects who's target is the same as the object specified in the jQuery object will be matched.

So, this is all the theory about how they work and why one configuration is supposed to be better than another. If you want to test real world performance, you'd have to devise some sort of performance test on event handler propagation and distribution probably in a scenario where you had a lot of "live" event handlers. That test is probably not easy to do because it may be hard to get timing info on the start/end of an event handler. You can't easily use a tool like jsperf for something like this.

Selecting an Element | Javascript vs Jquery

Whats the difference between an element selected by Javascript and the same element selected with jQuery?

There's no difference in the element, but jQuery gives you back the element wrapped in a jQuery object, whereas the DOM gives you a reference to the element itself. jQuery objects are sets of elements (since it lets you select more than one and treat them as a set).

To get the element itself from the jQuery object, you can index into it like an array:

var rawElement = jqSelect[0];
alert(rawElement.dataset.name);

var jsSelect = document.getElementById("jsSelect");snippet.log(jsSelect.dataset.name);
var jqSelect = $("#jsSelect");var rawElement = jqSelect[0];snippet.log(rawElement.dataset.name);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><div id="jsSelect" data-name="Javascript"></div><!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 --><script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

.live() vs .on() method

You're not using it correctly. The replacement for .live() is $(document).on() with the event and handler being passed in, of course... for example:

$(document).on('click', '#myElement', function() { 
//... some function ...
});

It's worth mentioning that before .on() ever came around, .live() was already considered an inefficient way to handle this kind of binding. .delegate() was recommended instead, and now .on() (using the delegator syntax).

Or as an example: instead of the document being the listener (which is what .live() used to do), you should pick the nearest ancestor that does not get destroyed with DOM manipulations. I honestly find the "jsdo.it" a bit clunky to use so I don't have the specific element in mind, but for example, given the structure:

<div id="ajax_container">
<button id="do_something">Clicky!</button>
<p>Some dynamically-loaded content</p>
</div>

Where the contents of ajax_container are replaced by an Ajax call (no need to show the code for that part), binding a non-destroyed listener (the container div) for that button's click event would look like:

$('#ajax_container').on('click', '#do_something', function() {
// do something
})

jQuery methods Vs jQuery selectors

First of all, yes nikhil was right. ID is unique identifier and can be only used once. If you are willing to apply same styles to several elements, or you to use it to select several elements together use class attribute. But however, i couldn't understand your question. But maybe this could help

there is function in javascript which is widely supported by almost all major browsers

document.querySelectorAll("div [id^=myId]");

in fact you could write your own library (well not as advanced one like jquery but)

var $ = function(selector){
return document.querySelectorAll(selector);
}

// and then you could use it like this
var elementsWithMyId = $("div [id^=myId]");
// where elementsWithMyId will contain array of all divs which's id start with myId

so as i understood your question, No. there is no magic happening behind jQuery selections it's just browser built in function which is kinda shortened by jquery. of course they added tons of new features, which would work like this:

var $ = function(selector){
var elementsArray = document.querySelectorAll(selector);

elementsArray.makeBlue = function(){
for(var i = 0; i < elementsArray.length; i++){
elementsArray[i].style.backgroundColor = "blue";
}
// so elementsArray will now have function to make all of its
// div blues. but if you want to have chain like that, we have to return this array not just make all of it blue
return elementsArray;
}

elementsArray.makeRed = function(){
for(var i = 0; i < elementsArray.length; i++){
elementsArray[i].style.backgroundColor = "red";
}
return elementsArray;
}

return elementsArray;
}

// so now you can use it like this

// this returns array which has options make blue, and make red so lets use make blue first
// makeBlue then returns itself, meaning it returns array which has again options of making itself red and blue so we can use makeRed now
$("div [id^=myId]").makeBlue().makeRed();

and thats it!

Are there any drawbacks to listen events on document level in jQuery?

From the jQuery documentation available here:

Event performance

In most cases, an event such as click occurs infrequently and performance is not a significant concern. However, high frequency events such as mousemove or scroll can fire dozens of times per second, and in those cases it becomes more important to use events judiciously. Performance can be increased by reducing the amount of work done in the handler itself, caching information needed by the handler rather than recalculating it, or by rate-limiting the number of actual page updates using setTimeout.

Attaching many delegated event handlers near the top of the document tree can degrade performance. Each time the event occurs, jQuery must compare all selectors of all attached events of that type to every element in the path from the event target up to the top of the document. For best performance, attach delegated events at a document location as close as possible to the target elements. Avoid excessive use of document or document.body for delegated events on large documents.

jQuery can process simple selectors of the form tag#id.class very quickly when they are used to filter delegated events. So, "#myForm", "a.external", and "button" are all fast selectors. Delegated events that use more complex selectors, particularly hierarchical ones, can be several times slower--although they are still fast enough for most applications. Hierarchical selectors can often be avoided simply by attaching the handler to a more appropriate point in the document. For example, instead of $("body").on("click", "#commentForm .addNew", addComment) use $("#commentForm").on("click", ".addNew", addComment).



Related Topics



Leave a reply



Submit