Question

With http://jsfiddle.net/mgs_jsfiddle/HXMCs/ why isn't the first event handler run, if the mouse is moved into the sub area?

<div class="top">
    <div class="sub"></div>
</div>

$(".top").bind("mouseover mouseout", function(e) {
});

$(".top").on("mouseover mouseout", ".sub", function(e) {
    e.stopPropagation();
});

Both handlers are attached to the top element. And the documentation for stopPropagation tells me that "this will not prevent other handlers on the same element from running". So shouldn't the first handler also be called?

Was it helpful?

Solution

Both of these events:

$(".top").bind("mouseover mouseout", function(e) {
});

$(".top").on("mouseover mouseout", ".sub", function(e) {
    e.stopPropagation();
});

are attached to .top. But the second one is a delegated event and jQuery emulates it like it is a normal event. If you remove stopPropagation:

$(".top").bind("mouseover mouseout", function(e) {
});

$(".top").on("mouseover mouseout", ".sub", function(e) {
});

you will notice that the second event is fired first as if it was attached directly to .sub. jQuery emulates the propagation for delegated events as if it is a normal event.

So obviously if a child element stops propagation the parent element will not receive the event. But as i mentioned it is just an emulation in jQuery.

UPDATE

Even though jQuery official site explains it pretty well on http://api.jquery.com/on/, i will try to explain on method briefly.

on method was introduced in jQuery 1.7. It is considered as a replacement for a couple of methods that were used before for binding events: bind, delegate and live. The last 2 of them were used for attaching delegated events. Now you can attach them with a single method on.

Regular event:

$(".top").on("mouseover mouseout", function(e) {

});

is completely the same as

$(".top").bind("mouseover mouseout", function(e) {

});

Delegated event:

$(".top").on("mouseover mouseout", ".sub", function(e) {

});

is the same as

$(".top").delegate(".sub", "mouseover mouseout", function(e) {

});

What are delegated events used for?

  • if your html is dynamically changed on the fly. E.g. you have a <table> and you bind some events on table rows:

    $("table tr").on("click", function(e) {
    
    });
    

    This event with not fire on dynamicaly inserted rows. A workaround can be using delegated events:

    $("table").on("click", "tr", function(e) {
    
    });
    

    The event is attached to the table not the rows. So it can handle any row that is inserted later.

  • if you have a massive bunch of similar elements. In this case if you bind events directly on the elements it may slow down your app. At least in IE:) So using delegated events may significantly increase the performance. You can look at the example from the 1st point.

How does delegated events work?

Let's take the example with <table>:

    $("table").on("click", "tr", function(e) {

    });

we attach the event on the table but ask it to check if the event was initiated on tr.

The rough implementation of the example above could look like this:

    $("table").on("click", function(e) {
        var tr = $(e.target).parentsUntil(this, 'tr');
        if (tr.length){
            //the event was triggered on tr inside table
            //do some stuff
        }
    });
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top