From b7ec6ddd45e27b54f3e094172b7eeb6949d4f71b Mon Sep 17 00:00:00 2001 From: Dave Methvin Date: Fri, 23 Nov 2012 15:03:55 -0500 Subject: [PATCH] Fix #12868. Use native focus/blur to get event order right. --- src/event.js | 20 +++++++++++++++++++- test/unit/event.js | 44 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 1 deletion(-) diff --git a/src/event.js b/src/event.js index aeee603f7..e92336a91 100644 --- a/src/event.js +++ b/src/event.js @@ -526,16 +526,34 @@ jQuery.event = { click: { // For checkbox, fire native event so checked state will be right trigger: function() { - if ( jQuery.nodeName( this, "input") && this.type === "checkbox" && this.click ) { + if ( jQuery.nodeName( this, "input" ) && this.type === "checkbox" && this.click ) { this.click(); return false; } } }, focus: { + // Fire native event if possible so blur/focus sequence is correct + trigger: function() { + if ( this !== document.activeElement && this.focus ) { + try { + this.focus(); + return false; + } catch ( e ) { + // IE<9 dies on focus to hidden element (#1486,#12518) + // If this happens, let .trigger() run the handlers + } + } + }, delegateType: "focusin" }, blur: { + trigger: function() { + if ( this === document.activeElement && this.blur ) { + this.blur(); + return false; + } + }, delegateType: "focusout" }, diff --git a/test/unit/event.js b/test/unit/event.js index f2f3cddd4..5fd3c1ca7 100644 --- a/test/unit/event.js +++ b/test/unit/event.js @@ -2860,6 +2860,50 @@ test("checkbox state (#3827)", function() { jQuery( cb ).triggerHandler( "click" ); }); +test("focus-blur order (#12868)", function() { + expect( 5 ); + + var $text = jQuery("#text1"), + $radio = jQuery("#radio1").focus(), + order; + + // IE6-10 fire focus/blur events asynchronously; this is the resulting mess. + // IE's browser window must be topmost for this to work properly!! + stop(); + $radio[0].focus(); + + setTimeout( function() { + + $text + .on( "focus", function(){ + equal( order++, 1, "text focus" ); + }) + .on( "blur", function(){ + equal( order++, 0, "text blur" ); + }); + $radio + .on( "focus", function(){ + equal( order++, 1, "radio focus" ); + }) + .on( "blur", function(){ + equal( order++, 0, "radio blur" ); + }); + + // Enabled input getting focus + order = 0; + equal( document.activeElement, $radio[0], "radio has focus" ); + $text.focus(); + setTimeout( function() { + equal( document.activeElement, $text[0], "text has focus" ); + + // Run handlers without native method on an input + order = 1; + $radio.triggerHandler( "focus" ); + start(); + }, 50 ); + }, 50 ); +}); + test("fixHooks extensions", function() { expect( 2 );