mirror of
https://github.com/jquery/jquery.git
synced 2024-11-23 02:54:22 +00:00
Fixed bubbling of live events (if an inner element handles an event first - and stops progatation - then the parent event doesn't encounter the event). Thanks to Irae for the patch. Fixes bug #3980.
This commit is contained in:
parent
0ae78024c2
commit
9aa0c69c43
@ -346,14 +346,18 @@ jQuery.fn = jQuery.prototype = {
|
||||
},
|
||||
|
||||
closest: function( selector ) {
|
||||
var pos = jQuery.expr.match.POS.test( selector ) ? jQuery(selector) : null;
|
||||
var pos = jQuery.expr.match.POS.test( selector ) ? jQuery(selector) : null,
|
||||
closer = 0;
|
||||
|
||||
return this.map(function(){
|
||||
var cur = this;
|
||||
while ( cur && cur.ownerDocument ) {
|
||||
if ( pos ? pos.index(cur) > -1 : jQuery(cur).is(selector) )
|
||||
if ( pos ? pos.index(cur) > -1 : jQuery(cur).is(selector) ) {
|
||||
jQuery.data(cur, "closest", closer);
|
||||
return cur;
|
||||
}
|
||||
cur = cur.parentNode;
|
||||
closer++;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
@ -571,9 +571,13 @@ function liveHandler( event ){
|
||||
}
|
||||
});
|
||||
|
||||
elems.sort(function(a,b) {
|
||||
return jQuery.data(a.elem, "closest") - jQuery.data(b.elem, "closest");
|
||||
});
|
||||
|
||||
jQuery.each(elems, function(){
|
||||
if ( this.fn.call(this.elem, event, this.fn.data) === false )
|
||||
stop = false;
|
||||
return (stop = false);
|
||||
});
|
||||
|
||||
return stop;
|
||||
|
@ -213,6 +213,11 @@ Z</textarea>
|
||||
<span>...</span><a id="linkWithNoHrefWithTabIndex" tabindex="1">Eat some funyuns</a><span>...</span>
|
||||
<span>...</span><a id="linkWithNoHrefWithNegativeTabIndex" tabindex="-1">Eat some funyuns</a><span>...</span>
|
||||
</div>
|
||||
|
||||
<div id="liveHandlerOrder">
|
||||
<span id="liveSpan1"><a href="#" id="liveLink1"></a></span>
|
||||
<span id="liveSpan2"><a href="#" id="liveLink2"></a></span>
|
||||
</div>
|
||||
</div>
|
||||
</dl>
|
||||
|
||||
|
@ -474,7 +474,7 @@ test("toggle(Function, Function, ...)", function() {
|
||||
});
|
||||
|
||||
test(".live()/.die()", function() {
|
||||
expect(42);
|
||||
expect(46);
|
||||
|
||||
var submit = 0, div = 0, livea = 0, liveb = 0;
|
||||
|
||||
@ -611,6 +611,29 @@ test(".live()/.die()", function() {
|
||||
|
||||
// Cleanup
|
||||
jQuery("#nothiddendivchild").die("click");
|
||||
|
||||
// Verify that .live() ocurs and cancel buble in the same order as
|
||||
// we would expect .bind() and .click() without delegation
|
||||
var lived = 0, livee = 0;
|
||||
|
||||
// bind one pair in one order
|
||||
jQuery('span#liveSpan1 a').live('click', function(){ lived++; return false; });
|
||||
jQuery('span#liveSpan1').live('click', function(){ livee++; });
|
||||
|
||||
jQuery('span#liveSpan1 a').click();
|
||||
equals( lived, 1, "Verify that only one first handler occurred." );
|
||||
equals( livee, 0, "Verify that second handler don't." );
|
||||
|
||||
// and one pair in inverse
|
||||
jQuery('#liveHandlerOrder span#liveSpan2').live('click', function(){ livee++; });
|
||||
jQuery('#liveHandlerOrder span#liveSpan2 a').live('click', function(){ lived++; return false; });
|
||||
|
||||
jQuery('span#liveSpan2 a').click();
|
||||
equals( lived, 2, "Verify that only one first handler occurred." );
|
||||
equals( livee, 0, "Verify that second handler don't." );
|
||||
|
||||
// Cleanup
|
||||
jQuery("span#liveSpan1 a, span#liveSpan1, span#liveSpan2 a, span#liveSpan2").die("click");
|
||||
});
|
||||
|
||||
/*
|
||||
|
@ -189,7 +189,7 @@ test("child and adjacent", function() {
|
||||
reset();
|
||||
|
||||
t( "Last Child", "p:last-child", ["sap"] );
|
||||
t( "Last Child", "a:last-child", ["simon1","anchor1","mark","yahoo","anchor2","simon"] );
|
||||
t( "Last Child", "a:last-child", ["simon1","anchor1","mark","yahoo","anchor2","simon","liveLink1","liveLink2"] );
|
||||
|
||||
t( "Nth-child", "#main form#form > *:nth-child(2)", ["text1"] );
|
||||
t( "Nth-child", "#main form#form > :nth-child(2)", ["text1"] );
|
||||
@ -278,7 +278,7 @@ test("pseudo (:) selectors", function() {
|
||||
expect(53);
|
||||
t( "First Child", "p:first-child", ["firstp","sndp"] );
|
||||
t( "Last Child", "p:last-child", ["sap"] );
|
||||
t( "Only Child", "a:only-child", ["simon1","anchor1","yahoo","anchor2"] );
|
||||
t( "Only Child", "a:only-child", ["simon1","anchor1","yahoo","anchor2","liveLink1","liveLink2"] );
|
||||
t( "Empty", "ul:empty", ["firstUL"] );
|
||||
t( "Enabled UI Element", "#form input:not([type=hidden]):enabled", ["text1","radio1","radio2","check1","check2","hidden2","name"] );
|
||||
t( "Disabled UI Element", "#form input:disabled", ["text2"] );
|
||||
@ -290,7 +290,7 @@ test("pseudo (:) selectors", function() {
|
||||
t( "Text Contains", "a:contains('Google Groups (Link)')", ["groups"] );
|
||||
t( "Text Contains", "a:contains('(Link)')", ["groups"] );
|
||||
|
||||
t( "Element Preceded By", "p ~ div", ["foo","fx-queue","fx-tests", "moretests","tabindex-tests"] );
|
||||
t( "Element Preceded By", "p ~ div", ["foo","fx-queue","fx-tests", "moretests","tabindex-tests", "liveHandlerOrder"] );
|
||||
t( "Not", "a.blog:not(.link)", ["mark"] );
|
||||
t( "Not - multiple", "#form option:not(:contains('Nothing'),#option1b,:selected)", ["option1c", "option1d", "option2b", "option2c", "option3d", "option3e"] );
|
||||
//t( "Not - complex", "#form option:not([id^='opt']:nth-child(-n+3))", [ "option1a", "option1d", "option2d", "option3d", "option3e"] );
|
||||
|
Loading…
Reference in New Issue
Block a user