jQuery extension for horizontal swipe gestures detection in Android, iOS and Windows Phone with Pointer and Touch events. Partially based on detect_swipe.
This extension has been created because most other scripts can't handle both Pointer and Touch events efficiently across browsers, and the browser implementation is not consistent either.
$('.selector').on('swipeleft', function(){ /* Left swipe gesture */ });
$('.selector').on('swiperight', function(){ /* Right swipe gesture */ });
Note: Settings are hard-coded and must be edited manually in the JS file.
var thresholdTime = 500;
Specifies the maximum allowed time in ms to consider gesture as a valid swipe.
var thresholdDistance = 64;
Specifies the minimum distance in px to consider gesture as a valid swipe.
var debug = false;
Specifies that debug info must be shown in the console using console.log()
. Useful to inspect relevant touch/pointer events.
This script was specifically designed for using swipe events within Apache Cordova apps, but it will work in any website as well. It has been tested on:
- Android 4.1, 4.2, 4.4 stock browsers
- Android 5.1 with updated Android System WebView
- Chrome 61
- Firefox 55
- Edge 38 on Windows Phone 10
- Internet Explorer Mobile 11 on Windows Phone 8.1
- Safari 11 on iOS 11
The script does not detect swipeup
nor swipedown
gestures, as they will inevitably interfere with regular vertical scrolling. It is intended mainly for mobile sites. Additionally, if you apply the swipe events to the entire HTML body, horizontal page scrolling will naturally be intercepted (and neutralized) by the event handler.
This script supports both the new PointerEvent and the legacy TouchEvent interfaces, prioritizing the former. Also supports the prefixed MSPointerEvent interface, exclusive to Internet Explorer 10.
Pointer Events, proposed by Microsoft, are designed to work in conjunction with the touch-action CSS property.
The touch-action CSS property specifies whether, and in what ways, a given region can be manipulated by the user via a touchscreen (for instance, by panning or zooming features built into the browser).
- Elements with
touch-action
unset
orauto
: ❎ (NOT recommended)- Will immediately trigger the
pointercancel
event before our swipe is detected, spoiling the gesture. (BAD) - As soon as
pointercancel
is triggered, the browser takes control of the gesture to perform regular pan actions. - Not even
e.PreventDefault()
will be enough to preventpointercancel
from firing.
- Will immediately trigger the
- Elements with
touch-action: none
: ❎ (NOT recommended)- Prevents the
pointercancel
event and allow us to correctly detect the horizontal swipe gesture. (GOOD) - Disables browser handling of all panning / scrolling and zooming gestures. (BAD)
- Prevents the
- Elements with
touch-action: pan-y
: ☑️ (RECOMMENDED)- Prevents the
pointercancel
event and allow us to correctly detect the horizontal swipe gesture. (GOOD) - Allows vertical scroll normally. (GOOD)
- Prevents the
In order to detect our horizontal gestures, ensure the object with the swiperight
or swipeleft
event has the touch-action
set specifically to pan-y
:
/* Attach event listener to our div.gestures element */
$('div.gestures').on('swipeleft', function(){ /* Left swipe gesture */ });
/* this div alone will detect H-gestures and allow V-scrolling */
div.gestures {
touch-action: pan-y;
}
div.gestures
also need to have the touch-action
property set, otherwise the browser could fire pointercancel
too soon to detect the swipe event. Using the asterisk selector is a solution for this:
/* this div and its child elements will detect H-gestures and allow V-scrolling */
div.gestures,
div.gestures * {
touch-action: pan-y;
}
The legacy Touch Events interface was implemented before the touch-action CSS property, therefore it is handled inconsistently among browsers. Some browser could fire touchcancel
(spoiling the swipe gesture) while others may never fire it. This script considers both scenarios and assumes that touchcancel
may be fired too soon. To prevent it, the script will first check the first few pixels swiped as follows:
- An initial 16 px horizontal swipe will use
e.preventDefault()
to keep checking for a valid H-swipe event- As soon as an horizontal gesture reaches
thresholdDistance
in pixels,swipeleft
orswiperight
is fired. - Gestures slower than
thresholdTime
milliseconds will be ignored (default 500 ms, half a second)
- As soon as an horizontal gesture reaches
- An initial 8 px vertical swipe will ignore our swipe listeners and delegate the gesture to the browser (for V-scrolling).
The pointercancel event is fired when the browser determines that there are unlikely to be any more pointer events, or if after the pointerdown event is fired, the pointer is then used to manipulate the viewport by panning, zooming, or scrolling.
The touchcancel event is fired when a touch point has been disrupted in an implementation-specific manner (for example, too many touch points are created).
The pointercancel event can be prevented using the touch-action
CSS property as explained earlier, while touchcancel cannot be stopped in pre-touch-action
browsers (Android 4, Chrome < 55). For this reason the script will listen to the first few pixels swiped before pointercancel
/ touchcancel
is fired as shown in the previous section and fire e.preventDefault
only when a potential horizontal swipe is detected.
This behaviour is designed to reduce the interference of the event listeners with regular scrolling and panning actions, and it works perfectly in conjunction with the proper touch-action
value in both modern and older browsers.