Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

stopPropagation and live() method. What am I missing?

I've read jQuery doc and I know that there's no point in using stopPropagation() if I use live() to bind event to elements, as the event with live() binds to document node so the event has already spred up. Said so, I figured nex code would alert 3 times,as stopPropagation doesn't stop anything:

<ul style="border:red solid 1px;">
    <li style="padding:10px; border:blue solid 1px;">
        <p style="border:green solid 1px;"><a href="#">link</a></p>
    </li>
    <li style="padding:10px; border:blue solid 1px;">
        <p style="border:green solid 1px;">no link</p>
    </li>
</ul>

<script type="text/javascript">
    $('a').live( "click", function( e ) {alert("link");e.stopPropagation()} );
    $('ul').live( "click", function( e ) {alert("ul");} );
    $('ul li').live( "click", function( e ) {alert("li");} );
</script>

When I click link I expected and alert of "li" and "ul", however stopPropagation is stopping the other events when it was supposed to be useless. What am I missing?

like image 677
Barleby Avatar asked Dec 19 '12 09:12

Barleby


1 Answers

As per documentation stopPropagation() does not work in live() as expected as live() only executes the event after it already bubbled up to the document.

However, if you are using jQuery 1.4.3 or later stopPropagation() started working.

live() was re-written several times since 1.4.3.
The live() documentation lists a lot of reasons why using other binding methods instead is preferred. It seems though that the information in the documentation refers to the 1.4.1 behaviour and doesn't seem to be 100% in sync with the actual current behaviour.

For example looking at the 1.7.1 Source which added on() it shows live() is using on():

live: function( types, data, fn ) {
    jQuery( this.context ).on( types, this.selector, data, fn );
    return this;
}

DEMO - Using your code and live in jQuery 1.4.1 - stopPropagation is not working, as expected

DEMO - Using your code and live in jQuery 1.4.3 - stopPropagation is now working

Summary

live() was re-written in 1.4.3. I assume due to delegate() having been added then.
live() has continuesly been updated with each version of jQuery as improvements were added.

In general to prevent any surprising results with live() it is better to follow the guidelines from the documentation and use the suggested methods for a given version of jQuery:

$(selector).live(events, data, handler);                // jQuery 1.3+
$(document).delegate(selector, events, data, handler);  // jQuery 1.4.3+
$(document).on(events, selector, data, handler);        // jQuery 1.7+

For completness I have added the live() source extract for 1.4.1 and 1.4.3 below.

1.4.1 source

live: {
    add: function(proxy, data, namespaces, live) {
        jQuery.extend(proxy, data || {});

        proxy.guid += data.selector + data.live;
        data.liveProxy = proxy;

        jQuery.event.add(this, data.live, liveHandler, data);

    },

    remove: function(namespaces) {
        if (namespaces.length) {
            var remove = 0,
                name = new RegExp("(^|\\.)" + namespaces[0] + "(\\.|$)");

            jQuery.each((jQuery.data(this, "events").live || {}), function() {
                if (name.test(this.type)) {
                    remove++;
                }
            });

            if (remove < 1) {
                jQuery.event.remove(this, namespaces[0], liveHandler);
            }
        }
    },
    special: {}
}

1.4.3 source

live: {
    add: function(handleObj) {
        jQuery.event.add(this, liveConvert(handleObj.origType, handleObj.selector), jQuery.extend({}, handleObj, {
            handler: liveHandler,
            guid: handleObj.handler.guid
        }));
    },

    remove: function(handleObj) {
        jQuery.event.remove(this, liveConvert(handleObj.origType, handleObj.selector), handleObj);
    }
}
like image 115
Nope Avatar answered Oct 30 '22 06:10

Nope