Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between .on() functions calls

Tags:

jquery

What is the difference between the following?

$(document).on("scroll",".wrapper1", function(){
   $(".wrapper2")
    .scrollLeft($(".wrapper1").scrollLeft());
});  

$('.wrapper1').on("scroll", function(){
        $(".wrapper2")
            .scrollLeft($(".wrapper1").scrollLeft());
});

When to should each functions be used exactly?

like image 410
PSR Avatar asked Apr 17 '13 10:04

PSR


2 Answers

The difference between these two are

$('.wrapper1').on("scroll", ....) binds the scroll event to only those elements which are present at the time of execution of this statement, ie if any new element with class wrapper1 is added dynamically after this statement is executed then the event handler will not get executed for those elements.

$(document).on("scroll",".wrapper1", ...) on the other hand will register one event handler to the document object and will make use of event bubbling to invoke the handler whenever scrolling happens within an element with class `wrapper``, so it will support dynamic addition of elements.

So when to prefer a method

you can prefer first method if you have only a limited number of elements and they are not dynamically added

Prefer the second method if you have lot of elements or these elements are added dynamically.

like image 126
Arun P Johny Avatar answered Nov 12 '22 00:11

Arun P Johny


The effect will be the same, but the way in which the event handler is having the event delivered is slightly different.

You are using .on() in each case, but a selector is not being used in the second version. The event is delegated in the first instance and is directly bound in the second. The .on() documentation states:

For direct events,

handler is called every time an event occurs on the selected elements, whether it occurs directly on the element or bubbles from a descendant (inner) element

For delegated events,

The handler is not called when the event occurs directly on the bound element, but only for descendants (inner elements) that match the selector

What happens is when an event is detected by the browser it bubbles up the DOM. At each element on the way up, jQuery will call the event handlers that have been attached. In the first version the event propagates all the way up to the document before jQuery checks if the event originated in a class="wrapper1" element. The second version, the event would stop bubbling earlier if the event was on a class="wrapper1" element.

The other difference is that the first version will still be able to bind the event handler if .wrapper1 does not exist when the page has finished loading, i.e. if the element is dynamically added the second version will not work. When the page loads and the jQuery executed $('.wrapper1') might not exist.

If .wrapper1 element(s) are not dynamic then you will probably find a (negligible) performance benefit of using the second version.

All that aside, the scroll event does not bubble and cannot be delegated. However, they can be delegated Again from the .on() documentation:

In all browsers, the load, scroll, and error events (e.g., on an element) do not bubble. In Internet Explorer 8 and lower, the paste and reset events do not bubble. Such events are not supported for use with delegation, but they can be used when the event handler is directly attached to the element generating the event.

So the only version that would work is the second one! See demo in the DevTools Console the document scroll output never appears.

like image 31
andyb Avatar answered Nov 11 '22 23:11

andyb