FastButton? Handling touch events for mobile?

817 views
Skip to first unread message

markww

unread,
Nov 5, 2012, 8:29:53 AM11/5/12
to google-we...@googlegroups.com
Hi,

I've got some buttons on a page which will primarily be used from mobile devices. The click handlers fire only after a 300ms delay (intentional on mobile devices as detailed here [https://developers.google.com/mobile/articles/fast_buttons]).

Looks like someone has tried to implement the above for GWT:

but I'm getting strange behavior from that FastButton implementation. Is there something baked into GWT 2.5 that does this for us?

Thanks

emurmur

unread,
Nov 5, 2012, 1:57:44 PM11/5/12
to google-we...@googlegroups.com
I took a quick look at the code you linked to in stackoverflow.  I think the code as written has a few problems.

(NOTE: I'm looking at code I wrote using the Elemental library as reference, so some of the calls might be different in the user library).

a) The code is not filtering touches aimed at the button; it calls TouchEvent.getTouches().  You want to call TouchEvent.getTargetTouches() on touchstart and touchmove to get the the touches just for your button.  You want to call TouchEvent.getChangedTouches() on touchend to get the end touch.
b) The code does not take into account multitouch.  On touchstart, you can check that a single touch is available and bail out if there is more than one.  Also, on touchstart, stash away the id of touch, then use this in touchmove and touchend to find your touch id in the array that is returned (in case the user has touched another finger later on).  You can also simplify and check for multiple touches on touchmove and touchend and bail again there.
c) I believe you need to call stopPropagation on touchstart, since you are handling the event. I don't see where they call event.preventDefault on the touchstart event  You can see that this happens in the click handlers, but not the touchstart.

There is also a simpler way.  If you don't care about dragging starting on a button, then you can simply call your click logic in the touchstart event (and make sure you call event.preventDefault, TouchEvent.getTargetTouches() and  check for single touch) and ignore touchmove and touchend.  All the touchmove and touchend stuff is to handle the case of allowing dragging to start on the button.

Ed

emurmur

unread,
Nov 5, 2012, 2:18:11 PM11/5/12
to google-we...@googlegroups.com
Anyplace I wrote event.preventDefault I really meant event.stopPropagation.

Ed

Ashton Thomas

unread,
Dec 16, 2012, 5:36:17 PM12/16/12
to google-we...@googlegroups.com
I wanted to take a shot at this implementation using the previous answer and Ed's comments:


Example with code: 

Not sure if I hit all the edge cases so if someone notices anything wrong, please let me know


- Ashton

Ashton Thomas

unread,
Dec 17, 2012, 8:58:39 AM12/17/12
to google-we...@googlegroups.com
Also, to get the full benefits of this you will want to test on a mobile device (that handles touch events and puts a delay on onClick).

On a desktop browser, you should notice no difference since onClick is fired immediately and there are no touch events.

To really see the benefit, rapidly click the "fast" buttons (using fast-press) and then try the same with the "slow" buttons (using regular clickHandler)

- Ashton 

Jens

unread,
Dec 17, 2012, 11:25:41 AM12/17/12
to google-we...@googlegroups.com
Looks nice although I think the real way GWT should go is to implement the Windows 8 approach. If you write an application for desktop and mobile all you need is:

- Device.isTouchEnabled()  // although I am not sure how to obtain that information

which allows you to swap out widgets that are more mouse or more touch friendly (e.g. change vertical mouse wheel scrolling to horizontal swipe scrolling) and

- widget.addPointer[up/down/move/../../..]Handler() 

which is an abstraction layer of user input so it does not matter if its a touch device or not. Regardless of device type these pointer events will fire as fast as possible. Using GWT, on desktop you emulate them using click events, on iOS/Android you emulate them using touch events and on Windows 8 you use IE10's pointer events directly. Thanks to deferred binding this shouldn't be that hard to implement.

Personally I think thats the way to go in the future.

-- J.


Mark Wyszomierski

unread,
Dec 18, 2012, 9:00:04 AM12/18/12
to google-we...@googlegroups.com
This is great Ashton. Will the press handlers fire when you're scrolling a page? For example:
  1. User presses down on a button.
  2. User starts to drag downward.
  3. Page starts scrolling (if page content tall enough for scrolling)
  4. User releases outside original button rectangle.
  5. Does that original button still fire a push event?
I tried this on the "Fast Clear" button at the bottom as a test,

Thanks


--
You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group.
To view this discussion on the web visit https://groups.google.com/d/msg/google-web-toolkit/-/y2H4Yk7xV5MJ.

To post to this group, send email to google-we...@googlegroups.com.
To unsubscribe from this group, send email to google-web-tool...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.

Ashton Thomas

unread,
Dec 18, 2012, 9:17:01 AM12/18/12
to google-we...@googlegroups.com
The PressEvent should only fire if the touchEnd happens over the element. If I understand correctly, the event should not fire if you scroll or somehow move your finger off the target.

However, there may be a situation on browsers with the elastic scroll where you try to scroll but there is no content so the browser shows the stretch/elastic animation - so physically your finger is off of the button but the browser still registers the touchEnd as over the element. This should fire a pressEvent.

I haven't looked into what happens in this situation.

Ashton Thomas

unread,
Dec 18, 2012, 4:52:01 PM12/18/12
to google-we...@googlegroups.com
I have since updated the FastPressElement to fix some issues pointed out by mark. I have also cleaned up some things. All the code is on Github. Feedback from people needing this solution would be awesome.

I believe this will work very well in the situations that call for it. (It's a huge difference once you start using it)



- Ashton
Reply all
Reply to author
Forward
0 new messages