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?
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
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.
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: {}
}
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);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With