Direct Vs. Delegated - Jquery .On()

Direct vs. Delegated - jQuery .on()

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.

Event delegation vs direct binding when adding complex elements to a page

You will create less CPU overhead in binding the events using $(<root-element>).on(<event>, <selector>) since you will be binding to a single "root" element instead of potentially many more single descendant elements (each bind takes time...).

That being said, you will incur more CPU overhead when the actual events occur as they have to bubble up the DOM to the "root" element.

Short-story: delegate saves CPU when binding event handlers; bind saves CPU when events trigger (e.g. a user clicks something).

So it's up to you to decide what point is more important for performance. Do you have available CPU when you add the new elements? If so then binding directly to the new elements would be the best for overall performance however if adding the elements is a CPU intensive operation you will probably want to delegate the event binding and let the event triggering create some extra CPU overhead from all the bubbling.

Note that:

$(<root-element>).on(<event>, <selector>, <event-handler>)

is the same as:

$(<root-element>).delegate(<selector>, <event>, <event-handler>)

and that:

$(<selector>).on(<event>, <event-handler>)

is the same as:

$(<selector>).bind(<event>, <event-handler>)

.on() is new in jQuery 1.7 and if you are using 1.7+ then .delegate(<selector>, <event>, <event-handler>) is just a short-cut for .on(<event>, <selector>, <event-handler>).

UPDATE

Here is a performance test showing that it is faster to delegate event binding than to bind to each element individually: http://jsperf.com/bind-vs-click/29. Sadly this performance test has been removed.

UPDATE

Here is a performance test showing that event triggering is faster when you bind directly to elements rather than delegate the binding: http://jsperf.com/jquery-delegate-vs-bind-triggering (Note that this isn't a perfect performance test since the binding methods are included in the test, but since delegate runs faster on binding it just means that bind is even faster relatively when talking about triggering)

Event Handling Delegation or Direct

It depends on the number of click events that are bound inside the container.

$(".container button").on("click", function(){});

If there are only a few events happening and the button is already on the page the event bound by above signature should do the work for you.

$(".container").on("click", "button", function(){});

When a element is dynamically added to your page then use Event Delegation wherein normal binding of events will not work.

The performance question comes into play based on how heavy event driven your application is.
Performance should not matter if that number is small. But lets say you have 1000 click events on the elements inside the container.

Would you create a click for all the common elements with the same functionality. In such cases you could use delegation, wherein the event will be attached to a single element, which can lead to less maintainable code and more readability.

how these two pieces of jQuery differ and the direct and delegated events model

I'm not 100% certain what you want to know, since the question you linked to ( Direct vs. Delegated - jQuery .on() ) seems to hold the answer to what you are asking for.

Here is again an explanation of the differences:

$('.loc-to-select').on('click',function(){
alert('here you go');
});

will search for all .loc-to-select elements that exist at that moment and bind the event handler to each of these elements.

The equivalent using the DOM API would be:

var elements = document.getElementsByClassName('loc-to-select');
for(var i = 0, l = elements.length; i < l; i++) {
elements[i].onclick = handler;
}

Now consider

$(document).on('click','.loc-to-select', function(){
alert('here you go');
});

only binds one event handler to document. It inspects every click event and test whether it originated from or within an element with class loc-to-select.

Again, the DOM equivalent (simplified):

document.body.onclick = function(event) {
if(event.target.className === 'loc-to-select') {
handler.call(this);
}
}

jQuery does not monitor the DOM for changes, it simply uses the fact that events are bubbling up the tree.

Finally, why don't they just make the second syntax (the delegated syntax) the default? It would seem to provide greater specificity and better performance (as mentioned in the docs)

Let's recap again what happens in event delegation: A single event handler is bound to one element to handle multiple (similar) elements. That means you need only search and touch x elements to handle y elements, where x << y, i.e. setting it up is faster.

It comes with a tradeoff though: Since the event is first traversing up the tree and the origin has to be evaluated, whether it matches or not, processing an event when it occurs takes more time.

Think about what happens if you would use event delegation for all click events on a page and you bind the handlers to document. You'd end up with n event handlers bound to document, and each of them would be executed on a single click. But out of those n, only one needs to be executed. This does not seem to be very performant.

With direct event handling, setup is slower, since you have to find all elements and bind the event handler to each of them. If there are not many elements, that's not a problem, but if there are many it can be. Apparently browsers perform worse the more event handlers are bound, but that might change or already has.

It's a tradeoff between having many event handlers bound to many elements executed fewer times and few event handlers bound to few elements executed many times.

Difference between delegating events to different elements in the DOM

There is no functional difference between the two. There is a (very) slight performance difference, though, as the first example requires the event to bubble up the DOM from the #toggleList element to the document. The second example needs only go as far up the DOM as the #toggleArea, so will be slightly faster.

The old live() method used to use the first method you outlined and was deprecated because of it.

In an ideal world, the delegated event should be assigned to the nearest parent element to those being dynamically created which is available in the DOM when document.ready fires. Avoid assigning it to document where possible.

jQuery .on delegation, only direct children in selector

In your listener function use event.stopPropagation to stop the event bubbling back up to a parent tr.

function listenerFunc(e) {
e.stopPropagation();

// Do your thing...
}

Jquery Difference B/w Jquery bind events

Have a look at the event delegation jQuery documentation

basically

$(document).on("click","#btn",callback);

will bind the click to the document DOM rather than the element directly which is useful when you are appending DOM elements to the window in which case the #btn selector will not exist yet.



Related Topics



Leave a reply



Submit