What does delegation do against plain ('click', ...)?

What is the difference between the performance and processing of these two different jQuery statements:

  • Number one :

    $('#selector1, #selector2, .class1').on('click', function () { //stuff }); 
  • Number two :

     $(document).on('click', '#selector1, #selector2, .class1', function () { //stuff }); 

I know that someone is doing delegation and the other is not.

But what does this mean?

Do you take any action when you press '#selector1, #selector2, .class1' ?

In the end, right?

+4
source share
4 answers

Number One will connect the click event to the elements that exist when this statement is executed. For example, the handler is directly tied to the actual elements that correspond when this call is made.

Number 2 will attach the click event to the document and upon receiving any clicks it checks whether the element that was actually clicked matches any of the specified selectors and if this will trigger the handler. This is more of an event than a simple connection.

So this means a few things:

  • Using number two, clicks on the elements that you add later will call the handler; with number one they will not.
  • Only bbbling events, such as click , work with number two (because it relies on an event bubbling the DOM to the document level).
  • If you use a delegated handler (number two), and another code captures the event on the actual element, and then cancels the propagation (bubbles) of the event, the delegated handler will not see it.
  • The delegated form (number two) should correspond to the element that was pressed (and, possibly, its ancestors), against the selector when clicked, which takes a non-zero time interval. Not necessarily a lot of time, but more than a direct handler (which should not do this). If you have many delegated handlers on the same element (in this case, on the document), you can start to notice.

There are times when it is better to use a handler with a direct connection, and times when delegating events (usually using something more focused than document ), however. Usually the dividing line between them is a decision call, but, for example, if you want to respond to clicks on the rows of the table, you are probably better off not attaching the click event to the table element using the tr selector, rather than attaching the click event for each individual row of the table , especially if you are dynamically updating the table. If you have a unique button that you know in the DOM when you attach a handler, and you want to run a specific function when that button (but not something else) is clicked, a direct handler probably makes more sense.

Here is an example ( live copy ):

HTML:

 <p>Click me</p> 

JavaScript:

 jQuery(function($) { $('p').on('click', function() { display("Directly-attached handler fired. Click this paragraph and note the difference in what happens compared to when you click the 'click me' paragraph."); }); $(document).on('click', 'p', function() { display("Delegated handler fired."); }); function display(msg) { $("<p>").html(msg).appendTo(document.body); } }); 

Note that when you click the β€œclick me” paragraph, you get two new paragraphs added to the document, one of which is the result of the first call to on , and the second is the result of the second. But keep in mind that if you press either of these two new paragraphs, you will only see the handler of the second on call (delegated), not the first. This is because these paragraphs did not exist when you connected the first handler.

+8
source
  • The on() method attaches an event handler for each of the elements corresponding to the jQuery object. If you pass an optional selector to the on() method, the handler will only fire if an event occurred on the descendant of this element.

    In this regard, in the first example, several event handlers will be added, since the jQuery object contains 3 elements. However, in the second example, one event handler will be connected that will handle the click event for all '#selector1, #selector2, .class1'

    Obviously, this leaves the first performance drawback if multiple elements are matched (since several event handlers are tied compared to the one included in the second example).

    For a small number of objects, choosing the second example from the first is the best optimization. However, if you have many elements (list items, rows in the table), you should seriously consider the second example compared to the first.

  • Since on() attaches handlers to each element consistent with the jQuery object, you cannot attach handlers directly to elements that are not already in the DOM (for example, if you want to add elements programmatically through code or through AJAX). In this case, the ability to provide a selector as the on() parameter becomes extremely useful; this allows you to attach an event handler to an element that is currently in the DOM, but which will handle events that fire elements that are not in the DOM yet (but which match the selector you specify).

    In another way, in the first example, jQuery attaches an event handler to all elements that match the selector #selector1, #selector2, .class1 ; and therefore will skip all elements that are not yet registered in the DOM.

    On the other hand, if you use the second example, jQuery attaches an event handler to all elements that correspond to the document selector (for example, one document element), and attaches a handler to it that will fire if the received event is triggered by an element matched by the #selector1, #selector2, .class1 selector #selector1, #selector2, .class1 ; this has the advantage of working for all future elements #selector1, #selector2, .class1 .

    Here you can see it; http://jsfiddle.net/kntR7/

  • Since number two is associated with document , any element that accepts a handler for the same event will receive the handler earlier (since document is the last place that the handler receives through event distribution) so if it wants to cancel the event using event.stopPropagation() or event.stopImmediatePropagation() , the handler will never be reached.

    Here you can see it; http://jsfiddle.net/mkNyU/

+5
source

For those familiar with the syntax of pre 1.7, here you can use on :

 //bind syntax $(selector).on(event, callback); $(selector).bind(event, callback); //delegate syntax $(parent).on(event, selector, callback); $(selector).delegate(selector, event, callback); //live syntax $(document).on(event, selector, callback); $(selector).live(event, callback); 

So your first line ( $('#selector1, #selector2, .class1').on('click', function) ) is the bind format for attaching events to existing elements.

Your second line ( $(document).on('click', '#selector1, #selector2, .class1', function) ) is the live format for attaching events to any element that matches the selector when an event occurs, regardless whether there are elements inside dom during the binding.

+1
source

The first binds 3+ event handlers (one for each element) that are lost after replacing the elements. The first will fail if the elements do not exist yet.

The second binds 1 event handler (one to document ), which will never be lost unless you explicitly delete it. And as soon as the handler is called here, the event already propagates to document . Each time you click anywhere on the page, jQuery internally checks to see if it was on any element that matches the selector of your choice, and starts the handler you gave if that happens. This only happens if the event propagated to document and was not stopped at a lower level element.

The second can be connected even before the document is ready, and it will still work, even if the elements do not yet exist.

0
source

Source: https://habr.com/ru/post/1381168/


All Articles