E1.17.2touch delay double activationdesignresearch

Touch delay can let two quick taps both count as valid

Aliases: ghost click · 300ms delay · double tap submit

What it is

A touch press emits a sequence: touchstart, touchend, then—after a compatibility delay—a synthetic click. If the person taps again because nothing seemed to happen, the second touch and the delayed click from the first may both count as valid submits. Delay making two quick taps valid is not two intents. It is one intent cloned by the event model, or two taps both landing before the lock.

Why it happens

To tell scroll, double-tap-zoom, and click apart, some WebViews still postpone the synthetic click by about 300 ms. If the app sends on touchend and again on click, one tap is two requests. Even listening only to click, a second tap inside those 300 ms queues two clicks; if the lock is taken asynchronously, both pass. 300 ms is also the window in which “no response, tap again” happens. Native apps lack the compatibility click, but sampling and UI jank can still let two pointerups arrive before the lock. Debouncing “ignore a second click within 500 ms” still fails if the first touchend and its derived click are treated as two entries.

Studying it

On a WebView with a 300 ms synthetic click and on a native control without it, do a single tap and a double tap on submit. Log the event sequence and request count.

Independent variables: listening to touchend, click, or both; lock synchronous versus next-frame; whether the 300 ms delay is disabled (viewport or touch-action). Dependent variables: requests on a single tap, requests on a double tap, whether click in the log lands after the second touch.

A desktop mouse on a touch emulator will not show the synthetic delay. Use a device or a WebView that still reproduces 300 ms.

Where it stops holding

Controls that need a double tap (map zoom, word select) must not treat the second touch as a duplicate submit. Game fire wants both taps. The 300 ms delay is rarer in modern browsers, but embedded WebViews and older Android still have it. A synchronous lock stops the cloned click too, so the fix is the lock, not guessing a delay number.

Applying it

  • Send the request on one event (click or pointerup, not both). Do not fire on touchend and again on click.
  • Take the lock at the synchronous start of the handler, not on an animation frame.
  • Set touch behavior on a non-zoom submit so the browser does not postpone click for double-tap zoom.
  • Verify on device with one tap and one pair ~200 ms apart on Pay. A single tap must not emit two requests; a pair with a working lock should still be one.

Related

  • Within the group: E1.17.1 Click-submit and Enter-submit must share one lock · E1.17.3 After a network failure the button must unlock into a clear error · E1.17.4 Optimistic UI can desynchronize unlock from result feedback
  • Adjacent: C2.10 Touch latency and tracking · C2.22 Double-taps and repeat fire · E1.09 Loading buttons
  • Search terms: ghost click · 300ms delay · touchend click

Cards in the same group

Quick Actions

Share

Share this page

ios_share

https://hci.top/en/handbook/E1.17.2