benmajor / jQuery-Touch-Events

A collection of mobile event plugins for jQuery.
MIT License
699 stars 225 forks source link

Bug (with fix): Bubbling (or fast) touch event can cause a single tap to always trigger a taphold due to hold_timer overwrite #156

Closed dustinbolton closed 4 years ago

dustinbolton commented 4 years ago

If more than one touch event is triggered within the threshold time before the end event triggers (eg. due to propagation) then the first timer(s) detecting how long a touch is being held is overwritten by the new timer (currently stored in the settings.hold_timer variable). This results in the first touch always being detected as a taphold. In my case I have a nested item so a single touch resulted in the first timer being overwritten.

A better solution than a single global variable holding the timer is for every touched object to have its own distinct variable holding the timer to be cleared on event end. This quick fix stores a hold_timer in $this.data rather than in the more global settings.hold_timer.

Edit: I initially thought fast touch events could also trigger this but I don't think a touch should ever register prior to its untouch other than due to propagation so I think this fix 100% solves the problem.

Fix: Change line 250: settings.hold_timer = window.setTimeout(function () { To: $this.data( 'hold_timer', window.setTimeout(function () {

Change line 289: }, threshold); To: }, threshold) );

Change line 296: window.clearTimeout(settings.hold_timer); To: window.clearTimeout($this.data( 'hold_timer' ));

Remove line 52 (optional): hold_timer: null,

benmajor commented 4 years ago

Thanks for the heads-up, @dustinbolton. I have now added this fix to the 2.0.1 release (see https://github.com/benmajor/jQuery-Touch-Events/commit/9a6e4c6a8a184b4c02a8381b7adf7796e702aaaa)

Thanks for suggestion!