Opened 5 years ago

Closed 5 years ago

#18125 closed defect (invalid)

Dojo touch events fire before non-touch counterparts (touch device only)

Reported by: neville1355 Owned by: neville1355
Priority: undecided Milestone: tbd
Component: Events Version: 1.10.0
Keywords: Cc:
Blocked By: Blocking:

Description

Found this while tracing down an issue with popups opening and closing immediately on tablets.

The skinny:

  • dojo/touch-> press and release are firing significantly faster than 'mousedown' and 'mouseup'... although both are firing
  • focusin/focusout also appears to be much slower than it should
  • Only on mobile browsers as far as I can see (test iPad 2 and Galaxy Tab 3 on chrome browser)

When trying to shift focus on click to a new popup I create programmatically, the popup closes immediately. Although I'm not sure, I believe it may be due to 'mousedown', 'mouseup', 'focusout' and 'focusin' firing after touch.press, which is what I'm using to open the popup.

In my case, I cannot use _HasDropDown because I need to open the popup at the touch.release phase.

I've attached two test cases that expose the problem:

1) The first one, "TestTouchEventsDojo?.html", is a lightweight test that outputs events in the order it receives them. On desktop browsers everything seems ok. On mobile browsers the touch events both fire significantly faster than anything else.

2)The second one, "TestTouchPopup?.html", is close to the specific use case I have in my application with the popup automatically closing.

It looks like dijit/focus doesn't use the dojo/touch module for looking at mousedown. However, changing that to touch.press also didn't resolve the issue.

The issue happens in 1.10.0, but we're currently on 1.9.2 still.

Attachments (3)

TestTouchEventsDojo.html (2.3 KB) - added by neville1355 5 years ago.
Log order of events as they are triggered for mousedown, mouseup, focusin, focusout, touch.press, and touch.release
TestTouchPopup.html (3.6 KB) - added by neville1355 5 years ago.
Programmatically open a drop down menu using dijit/popup and then transfer focus to the menu
FocusBugSimplified.html (1.7 KB) - added by neville1355 5 years ago.
Try to send focus on click from one node to another. Works on desktop, does not work on tablet.

Download all attachments as: .zip

Change History (10)

Changed 5 years ago by neville1355

Attachment: TestTouchEventsDojo.html added

Log order of events as they are triggered for mousedown, mouseup, focusin, focusout, touch.press, and touch.release

Changed 5 years ago by neville1355

Attachment: TestTouchPopup.html added

Programmatically open a drop down menu using dijit/popup and then transfer focus to the menu

comment:1 Changed 5 years ago by bill

Component: GeneralEvents
Owner: set to neville1355
Status: newpending

dojo/touch-> press and release are firing significantly faster than 'mousedown' and 'mouseup'... although both are firing

Yes, that's expected behavior and happens without dojo too. There's a 300ms delay to see if the touch action is the start of a scroll/zoom before the faux mouse events are generated.

So, I don't see any bug in dojo here?

comment:2 Changed 5 years ago by neville1355

Status: pendingnew

I see.

What's the correct way to programmatically focus on another element that acts on blur then (the #2 case)?

It seems like dijit/focus is unintentionally blurring elements because it listens to focusin/focusout/mousedown to update the focus stack.

Changed 5 years ago by neville1355

Attachment: FocusBugSimplified.html added

Try to send focus on click from one node to another. Works on desktop, does not work on tablet.

comment:3 Changed 5 years ago by neville1355

Added new attachment which demonstrates the core issue we're having in a simplified manner.

On touch.release, send focus from node #1 to adjacent node #2.

On desktop the focus transfers correctly. On tablet (iOS and Android) the focus moves then immediately is transfered back to the origin.

comment:4 Changed 5 years ago by bill

Status: newpending

I guess the mouseup event on button1 focuses it. Do you have some reason to believe that's due to dojo/focus rather than just how the browser works? You could try this whole simplified test case w/out any dojo at all and I suspect you'd see the same behavior.

Presumably you should transfer focus on *click*, not touch.release.

Is the issue that you don't want to wait 300ms? In that case, move focus on click, but use the dojoClick feature by setting the dojoClick property on that node to true (as documented in dojo/touch).

Last edited 5 years ago by bill (previous) (diff)

comment:5 Changed 5 years ago by neville1355

Status: pendingnew

Hey Bill,

Thanks for your feedback. I think you're right in that this is more of a core browser issue than anything to do with dojo. Specifically I traced this issue on the chromium project: https://code.google.com/p/chromium/issues/detail?id=278945

Furthermore, I isolated the issue to the browser's native behaviour to focus on click which occurs (like you said) 300ms after touch.release.

In my particular case I'm focusing on in response to a gesture as defined in dojox/gesture/Tap, which fires on touch.release; Click will always pull focus away after I programmatically assign it.

Thanks for the heads up on dojoClick, definitely something to consider.

I'm going to experiment more and reply here when I have further findings.

comment:6 Changed 5 years ago by neville1355

Just to update this bug thread:

I experimented with adding code to the default Element.prototype.focus() function to queue focus requests while touch events were in transit... Although this worked, it felt horrible hacky and overly invasive.

I also found that the Tap gesture fires on touch.release instead of click (maybe this was made before dojoClick was added?).

My fix was to update the Tap gesture to fire on click instead of mouseup, which incorporates dojoClick "fast-click" if the desired node supports it. Also, I updated my tappable nodes with dojoClick = false in order to get the native click event and focus on that instead.

You should be able to close this bug as I believe it is not a dojo issue, and dojo has a valid workaround (dojoClick = false).

comment:7 Changed 5 years ago by bill

Resolution: invalid
Status: newclosed

OK thanks.

Note: See TracTickets for help on using tickets.