diff options
author | kborchers <kris.borchers@gmail.com> | 2011-12-15 12:43:28 -0600 |
---|---|---|
committer | kborchers <kris.borchers@gmail.com> | 2011-12-15 12:43:28 -0600 |
commit | a8d0e4c8043b42257c51a1d65cd07d1042538062 (patch) | |
tree | b68c1125ad3f821fb9637b87dfe245a3d1e6577c /ui/jquery.ui.menu.js | |
parent | aa8c4770a9a88cc4a870f4adf33ba2466e30bfcf (diff) | |
download | jquery-ui-a8d0e4c8043b42257c51a1d65cd07d1042538062.tar.gz jquery-ui-a8d0e4c8043b42257c51a1d65cd07d1042538062.zip |
Menu: Fix focus handling to keep focus on the menu and prevent jumping around within the menu on mousedown
Diffstat (limited to 'ui/jquery.ui.menu.js')
-rw-r--r-- | ui/jquery.ui.menu.js | 76 |
1 files changed, 35 insertions, 41 deletions
diff --git a/ui/jquery.ui.menu.js b/ui/jquery.ui.menu.js index 0263cff65..6e534b1ba 100644 --- a/ui/jquery.ui.menu.js +++ b/ui/jquery.ui.menu.js @@ -54,14 +54,13 @@ $.widget( "ui.menu", { }, "click .ui-menu-item:has(a)": function( event ) { event.stopImmediatePropagation(); - var target = $( event.currentTarget ); - // it's possible to click an item without hovering it (#7085) - if ( !this.active || ( this.active[ 0 ] !== target[ 0 ] ) ) { - this.focus( event, target ); - } this.select( event ); - // Redirect focus to the menu. - this.element.focus(); + // Redirect focus to the menu with a delay for firefox + this._delay( function() { + if ( !this.element.is(":focus") ) { + this.element.focus(); + } + }, 20); }, "mouseover .ui-menu-item": function( event ) { event.stopImmediatePropagation(); @@ -72,9 +71,21 @@ $.widget( "ui.menu", { }, "mouseleave": "collapseAll", "mouseleave .ui-menu": "collapseAll", - "mouseout .ui-menu-item": "blur", "focus": function( event ) { - this.focus( event, $( event.target ).children( ".ui-menu-item:first" ) ); + var firstItem = this.element.children( ".ui-menu-item" ).eq( 0 ); + if ( this._hasScroll() && !this.active ) { + var menu = this.element; + menu.children().each( function() { + var currentItem = $( this ); + if ( currentItem.offset().top - menu.offset().top >= 0 ) { + firstItem = currentItem; + return false; + } + }); + } else if ( this.active ) { + firstItem = this.active; + } + this.focus( event, firstItem ); }, blur: function( event ) { this._delay( function() { @@ -283,21 +294,6 @@ $.widget( "ui.menu", { focus: function( event, item ) { this.blur( event ); - if ( this._hasScroll() ) { - var borderTop = parseFloat( $.curCSS( this.activeMenu[0], "borderTopWidth", true ) ) || 0, - paddingTop = parseFloat( $.curCSS( this.activeMenu[0], "paddingTop", true ) ) || 0, - offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop, - scroll = this.activeMenu.scrollTop(), - elementHeight = this.activeMenu.height(), - itemHeight = item.height(); - - if ( offset < 0 ) { - this.activeMenu.scrollTop( scroll + offset ); - } else if ( offset + itemHeight > elementHeight ) { - this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight ); - } - } - this.active = item.first() .children( "a" ) .addClass( "ui-state-focus" ) @@ -463,15 +459,14 @@ $.widget( "ui.menu", { }, nextPage: function( event ) { + if ( !this.active ) { + this.focus( event, this.activeMenu.children( ".ui-menu-item" ).first() ); + return; + } + if ( this.last() ) { + return; + } if ( this._hasScroll() ) { - if ( !this.active ) { - this.focus( event, this.activeMenu.children( ".ui-menu-item" ).first() ); - return; - } - if ( this.last() ) { - return; - } - var base = this.active.offset().top, height = this.element.height(), result; @@ -488,15 +483,14 @@ $.widget( "ui.menu", { }, previousPage: function( event ) { + if ( !this.active ) { + this.focus( event, this.activeMenu.children( ".ui-menu-item" ).first() ); + return; + } + if ( this.first() ) { + return; + } if ( this._hasScroll() ) { - if ( !this.active ) { - this.focus( event, this.activeMenu.children( ".ui-menu-item" ).first() ); - return; - } - if ( this.first() ) { - return; - } - var base = this.active.offset().top, height = this.element.height(), result; @@ -512,7 +506,7 @@ $.widget( "ui.menu", { }, _hasScroll: function() { - return this.element.height() < this.element.prop( "scrollHeight" ); + return this.element.outerHeight() < this.element.prop( "scrollHeight" ); }, select: function( event ) { |