Fixes #7340. Use a single capturing handler to simulate bubbling focusin/focusout event on non-IE browsers. Allow native DOM methods to fire events other than the currently active one back into jQuery.
This commit is contained in:
parent
2d0bc7ce72
commit
55ec6a71d2
32
src/event.js
32
src/event.js
|
@ -70,10 +70,10 @@ jQuery.event = {
|
|||
}
|
||||
|
||||
if ( !eventHandle ) {
|
||||
elemData.handle = eventHandle = function() {
|
||||
elemData.handle = eventHandle = function( e ) {
|
||||
// Handle the second event of a trigger and when
|
||||
// an event is called after a page has unloaded
|
||||
return typeof jQuery !== "undefined" && !jQuery.event.triggered ?
|
||||
return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ?
|
||||
jQuery.event.handle.apply( eventHandle.elem, arguments ) :
|
||||
undefined;
|
||||
};
|
||||
|
@ -380,7 +380,7 @@ jQuery.event = {
|
|||
target[ "on" + targetType ] = null;
|
||||
}
|
||||
|
||||
jQuery.event.triggered = true;
|
||||
jQuery.event.triggered = event.type;
|
||||
target[ targetType ]();
|
||||
}
|
||||
|
||||
|
@ -391,7 +391,7 @@ jQuery.event = {
|
|||
target[ "on" + targetType ] = old;
|
||||
}
|
||||
|
||||
jQuery.event.triggered = false;
|
||||
jQuery.event.triggered = undefined;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -868,19 +868,33 @@ function trigger( type, elem, args ) {
|
|||
// Create "bubbling" focus and blur events
|
||||
if ( document.addEventListener ) {
|
||||
jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
|
||||
|
||||
// Attach a single capturing handler while someone wants focusin/focusout
|
||||
var attaches = 0;
|
||||
|
||||
jQuery.event.special[ fix ] = {
|
||||
setup: function() {
|
||||
this.addEventListener( orig, handler, true );
|
||||
if ( attaches++ === 0 ) {
|
||||
document.addEventListener( orig, handler, true );
|
||||
}
|
||||
},
|
||||
teardown: function() {
|
||||
this.removeEventListener( orig, handler, true );
|
||||
if ( --attaches === 0 ) {
|
||||
document.removeEventListener( orig, handler, true );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function handler( e ) {
|
||||
e = jQuery.event.fix( e );
|
||||
function handler( donor ) {
|
||||
// Donor event is always a native one; fix it and switch its type.
|
||||
// Let focusin/out handler cancel the donor focus/blur event.
|
||||
var e = jQuery.event.fix( donor );
|
||||
e.type = fix;
|
||||
return jQuery.event.handle.call( this, e );
|
||||
e.originalEvent = {};
|
||||
jQuery.event.trigger( e, null, e.target );
|
||||
if ( e.isDefaultPrevented() ) {
|
||||
donor.preventDefault();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1966,6 +1966,31 @@ test("window resize", function() {
|
|||
ok( !jQuery._data(window, "__events__"), "Make sure all the events are gone." );
|
||||
});
|
||||
|
||||
test("focusin bubbles", function() {
|
||||
expect(4);
|
||||
|
||||
var input = jQuery( '<input type="text" />' ).prependTo( "body" ),
|
||||
order = 0;
|
||||
|
||||
jQuery( "body" ).bind( "focusin.focusinBubblesTest", function(){
|
||||
equals( 1, order++, "focusin on the body second" );
|
||||
});
|
||||
|
||||
input.bind( "focusin.focusinBubblesTest", function(){
|
||||
equals( 0, order++, "focusin on the element first" );
|
||||
});
|
||||
|
||||
// DOM focus method
|
||||
input[0].focus();
|
||||
// jQuery trigger, which calls DOM focus
|
||||
order = 0;
|
||||
input[0].blur();
|
||||
input.trigger( "focus" );
|
||||
|
||||
input.remove();
|
||||
jQuery( "body" ).unbind( "focusin.focusinBubblesTest" );
|
||||
});
|
||||
|
||||
/*
|
||||
test("jQuery(function($) {})", function() {
|
||||
stop();
|
||||
|
|
Loading…
Reference in a new issue