Opened 6 months ago

#15103 new bug

Make an element draggable can lead to unfocusable elements being focused on click (mouseup) in IE11

Reported by: JoolsCaesar Owned by:
Priority: minor Milestone: none
Component: ui.draggable Version: 1.12.1
Keywords: Cc:
Blocked by: Blocking:

Description

When child elements of focusable elements have certain CSS properties, those child elements become focusable in IE11. This is a bug with IE11 that Microsoft have no intention of fixing. https://connect.microsoft.com/IE/feedback/details/2499233/ie11-elements-with-display-inline-block-which-are-children-of-focusable-elements-can-be-given-focus-even-if-they-are-not-themselves-focusable

The problem often isn't noticeable unless you have css focus highlighting as described in the bug.

jQuery UI's draggable has a piece of code where it focuses draggable elements on mouse up:

_mouseUp: function( event ) {
   ...
   // Only need to focus if the event occurred on the draggable itself, see #10527
   if ( this.handleElement.is( event.target ) ) {
      
      // The interaction is over; whether or not the click resulted in a drag,
      // focus the element
      this.element.trigger("focus");
   }

In most browsers this has the desired effect, focusing the closest focusable element, otherwise having no effect. However in IE11 it is not unusual for this to lead to the focusing of an element that should not be focusable. While the focusabilty is not jquery UI's fault, the end result is worse than if the item was not draggable, because a programatic focus is treated by IE11 as though it was a tab-focus and triggers auto scrolling.

See this jsfiddle as an example: https://jsfiddle.net/JoolsCaesar/ttbzseyn/ Scroll the div until you can see the text "Inner bottom". Click the text and it will auto scroll the content back to the top. This does not occur if you comment out the line making it draggable.

See this abstract of the relevant code which merely calls focus() on mouseup: https://jsfiddle.net/JoolsCaesar/rfs49p56/ Follow the same steps as above and observe the same pattern.

The workaround I'm currently using is to change the line of code that does the focussing, to first check that the element it's focusing should be focusable:

that.element.closest(':focusable').focus();

Change History (0)

Note: See TracTickets for help on using tickets.