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
5 changed files with 43 additions and 7 deletions
|
@ -346,14 +346,18 @@ jQuery.fn = jQuery.prototype = {
|
||||||
},
|
},
|
||||||
|
|
||||||
closest: function( selector ) {
|
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(){
|
return this.map(function(){
|
||||||
var cur = this;
|
var cur = this;
|
||||||
while ( cur && cur.ownerDocument ) {
|
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;
|
return cur;
|
||||||
|
}
|
||||||
cur = cur.parentNode;
|
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(){
|
jQuery.each(elems, function(){
|
||||||
if ( this.fn.call(this.elem, event, this.fn.data) === false )
|
if ( this.fn.call(this.elem, event, this.fn.data) === false )
|
||||||
stop = false;
|
return (stop = false);
|
||||||
});
|
});
|
||||||
|
|
||||||
return stop;
|
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="linkWithNoHrefWithTabIndex" tabindex="1">Eat some funyuns</a><span>...</span>
|
||||||
<span>...</span><a id="linkWithNoHrefWithNegativeTabIndex" tabindex="-1">Eat some funyuns</a><span>...</span>
|
<span>...</span><a id="linkWithNoHrefWithNegativeTabIndex" tabindex="-1">Eat some funyuns</a><span>...</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div id="liveHandlerOrder">
|
||||||
|
<span id="liveSpan1"><a href="#" id="liveLink1"></a></span>
|
||||||
|
<span id="liveSpan2"><a href="#" id="liveLink2"></a></span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</dl>
|
</dl>
|
||||||
|
|
||||||
|
|
|
@ -474,7 +474,7 @@ test("toggle(Function, Function, ...)", function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test(".live()/.die()", function() {
|
test(".live()/.die()", function() {
|
||||||
expect(42);
|
expect(46);
|
||||||
|
|
||||||
var submit = 0, div = 0, livea = 0, liveb = 0;
|
var submit = 0, div = 0, livea = 0, liveb = 0;
|
||||||
|
|
||||||
|
@ -611,6 +611,29 @@ test(".live()/.die()", function() {
|
||||||
|
|
||||||
// Cleanup
|
// Cleanup
|
||||||
jQuery("#nothiddendivchild").die("click");
|
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();
|
reset();
|
||||||
|
|
||||||
t( "Last Child", "p:last-child", ["sap"] );
|
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"] );
|
||||||
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);
|
expect(53);
|
||||||
t( "First Child", "p:first-child", ["firstp","sndp"] );
|
t( "First Child", "p:first-child", ["firstp","sndp"] );
|
||||||
t( "Last Child", "p:last-child", ["sap"] );
|
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( "Empty", "ul:empty", ["firstUL"] );
|
||||||
t( "Enabled UI Element", "#form input:not([type=hidden]):enabled", ["text1","radio1","radio2","check1","check2","hidden2","name"] );
|
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"] );
|
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('Google Groups (Link)')", ["groups"] );
|
||||||
t( "Text Contains", "a:contains('(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", "a.blog:not(.link)", ["mark"] );
|
||||||
t( "Not - multiple", "#form option:not(:contains('Nothing'),#option1b,:selected)", ["option1c", "option1d", "option2b", "option2c", "option3d", "option3e"] );
|
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"] );
|
//t( "Not - complex", "#form option:not([id^='opt']:nth-child(-n+3))", [ "option1a", "option1d", "option2d", "option3d", "option3e"] );
|
||||||
|
|
Loading…
Add table
Reference in a new issue