Skip to content

Commit 573e7e6

Browse files
Ryan Oriecuiascottgonzalez
Ryan Oriecuia
authored andcommitted
Autocomplete: Fix IE/Edge scrolling issues
IE11 and scrolling autocompletes didn't get along great; this should help fix their relationship. When you click on an autocomplete scrollbar in IE11, the menu temporarily gains focus, which caused a couple problems. 1. Depending on how long you clicked, the dropdown could close. 2. Scrolling down by clicking the scrollbar's down arrow would misbehave. The list would pop back up to the top with the first item selected. We can fix both problems by modifying the focus/blur handling a bit. 1. There is a flag to instruct the control to ignore blurs, but it was getting cleared too quickly; when the code refocused the input after it was blurred, IE would send *another* blur event, which wasn't getting ignored and would close the dropdown. We now wait for the focus/blur pair to process before clearing the flag. 2. We remove the tabindex from the dropdown menu, which prevents menu's focus handler from firing. When you focus a menu, it will select the first menu item if none are selected. Selecting a menu item will scroll it into view if it's not visible. This combination of behaviors was causing the strange behavior when attempting to scroll down. I couldn't figure out a way to write a unit test for this, since it's IE only and seems to require user interaction. You can verify the previous behavior (and the fix) on `demos/autocomplete/maxheight.html` Fixes #9638 Closes jquerygh-1785
1 parent 4b9f324 commit 573e7e6

File tree

1 file changed

+11
-23
lines changed

1 file changed

+11
-23
lines changed

ui/widgets/autocomplete.js

Lines changed: 11 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -200,11 +200,6 @@ $.widget( "ui.autocomplete", {
200200
this.previous = this._value();
201201
},
202202
blur: function( event ) {
203-
if ( this.cancelBlur ) {
204-
delete this.cancelBlur;
205-
return;
206-
}
207-
208203
clearTimeout( this.searching );
209204
this.close( event );
210205
this._change( event );
@@ -220,31 +215,24 @@ $.widget( "ui.autocomplete", {
220215
role: null
221216
} )
222217
.hide()
218+
219+
// Support: IE 11 only, Edge <= 14
220+
// For other browsers, we preventDefault() on the mousedown event
221+
// to keep the dropdown from taking focus from the input. This doesn't
222+
// work for IE/Edge, causing problems with selection and scrolling (#9638)
223+
// Happily, IE and Edge support an "unselectable" attribute that
224+
// prevents an element from receiving focus, exactly what we want here.
225+
.attr( {
226+
"unselectable": "on"
227+
} )
223228
.menu( "instance" );
224229

225230
this._addClass( this.menu.element, "ui-autocomplete", "ui-front" );
226231
this._on( this.menu.element, {
227232
mousedown: function( event ) {
228233

229-
// prevent moving focus out of the text field
234+
// Prevent moving focus out of the text field
230235
event.preventDefault();
231-
232-
// IE doesn't prevent moving focus even with event.preventDefault()
233-
// so we set a flag to know when we should ignore the blur event
234-
this.cancelBlur = true;
235-
this._delay( function() {
236-
delete this.cancelBlur;
237-
238-
// Support: IE 8 only
239-
// Right clicking a menu item or selecting text from the menu items will
240-
// result in focus moving out of the input. However, we've already received
241-
// and ignored the blur event because of the cancelBlur flag set above. So
242-
// we restore focus to ensure that the menu closes properly based on the user's
243-
// next actions.
244-
if ( this.element[ 0 ] !== $.ui.safeActiveElement( this.document[ 0 ] ) ) {
245-
this.element.trigger( "focus" );
246-
}
247-
} );
248236
},
249237
menufocus: function( event, ui ) {
250238
var label, item;

0 commit comments

Comments
 (0)