This document provides an introduction to touch and pointer events. It discusses how touch events work on mobile and tablet devices compared to mouse events on desktop. It notes some limitations of relying only on mouse events for touch devices, such as delayed event dispatching and lack of mouse movement tracking. The document then introduces touch events and how they map to mouse events. It provides examples of how to handle both touch and mouse events together to support different input methods. It also discusses some newer pointer events and media queries for detecting input capabilities. Overall, the document aims to help developers make their websites work well across both touch and non-touch environments.
2. about me...
• senior accessibility consultant at The Paciello Group
• previously developer relations at Opera
• co-editor Touch Events Level 2
• WG chair and co-editor Pointer Events Level 2
29. • too many touchmove events prevent mouse compatibility events
after touchend (not considered a "clean" tap)
• too many touchmove events on activatable elements can lead to
touchcancel (in old Chrome/Browser versions)
• not all browsers consistently send touchmove
• differences in focus / blur and some mouse compatibility events
(e.g. mouseenter / mouseleave )
• some events may only fire when tapping away to another focusable
element (e.g. blur )
some browsers outright weird...
34. / feature detection for touch events */
if ( 'ontouchstart' in window ) {
/* some clever stuff here */
}
/* older browsers have flaky support so more
hacky tests needed...use Modernizr.touch or similar */
36. /* conditional "touch OR mouse/keyboard" event binding */
if ('ontouchstart' in window) {
// set up event listeners for touch
...
} else {
// set up event listeners for mouse/keyboard
...
}
57. further scenarios?
• desktop with external touchscreen
• touchscreen laptop with non-touch second screen
• touchscreen laptop with trackpad/mouse
• ...and other permutations?
62. /* feature detection for touch events */
if ('ontouchstart' in window) {
/* browser supports touch events but user is
not necessarily using touch (exclusively) */
/* it could be a mobile, tablet, desktop, fridge ... */
}
70. /* Naive uses of Interaction Media Features */
@media (pointer: fine) {
/* primary input has fine pointer precision...
so make all buttons/controls small? */
}
@media (hover: hover) {
/* primary input has hover...so we can rely on it? */
}
/* pointer and hover only check "primary" input, but
what if there's a secondary input that lacks capabilities? */
71. /* Better uses of Interaction Media Features */
@media (any-pointer: coarse) {
/* at least one input has coarse pointer precision...
provide larger buttons/controls for touch */
}
/* test for *any* "least capable" inputs (primary or not) */
Limitation: [mediaqueries-4] any-hover can't be used to detect mixed hover and non-hover
capable pointers. Also, pointer / hover / any-pointer / any-hover don't cover non-pointer
inputs (e.g. keyboards) – always assume non-hover-capable inputs
@media (any-hover: none) {
/* at least one input lacks hover capability...
don't rely on it or avoid altogether */
}
90. /* DON'T DO THIS:
conditional "touch OR mouse/keyboard" event binding */
if ('ontouchstart' in window) {
// set up event listeners for touch
foo.addEventListener('touchend', ...);
...
} else {
// set up event listeners for mouse/keyboard
foo.addEventListener('click', ...);
...
}
92. /* DO THIS:
doubled-up "touch AND mouse/keyboard" event binding */
// set up event listeners for touch
foo.addEventListener('touchend', ...);
// set up event listeners for mouse/keyboard
foo.addEventListener('click', ...);
/* but this would fire our function twice for touch? */
patrickhlauke.github.io/touch/tests/event-listener_naive-event-doubling.html
93. /* DO THIS:
doubled-up "touch AND mouse/keyboard" event binding */
// set up event listeners for touch
foo.addEventListener('touchend', function(e) {
// prevent compatibility mouse events and click
e.preventDefault();
...
});
// set up event listeners for mouse/keyboard
foo.addEventListener('click', ...);
patrickhlauke.github.io/touch/tests/event-listener_naive-event-doubling-fixed.html
116. suppressing 300ms delay
if your code does rely on handling click / mouse events:
• "mobile optimised" <meta name="viewport"
content="width=device-width">
• add touch-action:manipulation in CSS (part of Pointer Events)
• use helper library like fastclick.js for older browsers
• make your viewport non-scalable...
127. interface Touch {
readonly attribute long identifier;
readonly attribute EventTarget target;
readonly attribute long screenX ;
readonly attribute long screenY ;
readonly attribute long clientX ;
readonly attribute long clientY ;
readonly attribute long pageX ;
readonly attribute long pageY ;
};
www.w3.org/TR/touch-events/#touch-interface
128. TouchList differences
touches
all touch points on screen
targetTouches
all touch points that started on the element
changedTouches
touch points that caused the event to fire
162. /* Touch Events – force */
partial interface Touch {
readonly attribute float radiusX;
readonly attribute float radiusY;
readonly attribute float rotationAngle;
readonly attribute float force ;
};
force : value in range 0 – 1 . if no hardware support 0
(some devices, e.g. Nexus 10, "fake" force based on radiusX / radiusY )
169. ...and some new inputs (though currently mapped to mouse)
Building Xbox One Apps using HTML and JavaScript
“ouTube: Xbox One Edge Browser sends Pointer Events
186. events fired on tap (Edge)
mousemove* >
pointerover > mouseover >
pointerenter > mouseenter >
pointerdown > mousedown >
focus
gotpointercapture >
pointermove > mousemove >
pointerup > mouseup >
lostpointercapture >
click >
pointerout > mouseout >
pointerleave > mouseleave
mouse events fired inline with pointer events
(for a primary pointer, e.g. first finger on screen)
187. IE10/IE11 quirks
• vendor-prefixed in IE10 ( MSPointerDown ...,
navigator.msMaxTouchPoints , -ms-touch-action )
• unprefixed in IE11 (but prefixed versions mapped for compatibility)
• event order (when click is fired) incorrect in IE10/IE11
see W3C Pointer Events WG mailing list - Jacob Rossi (Microsoft)
188. Chrome, Edge (on mobile), IE11 (Windows Phone 8.1update1) support
both Touch Events and Pointer Events
w3c.github.io/pointerevents/#mapping-for-devices-that-do-not-support-hover
190. about:flags in Microsoft Edge to turn on touch events on desktop
(e.g. touch-enabled laptops) – off by default for site compatibility
191. ... when touch events also
supported (Edge)
pointerover > pointerenter > pointerdown >
touchstart >
pointerup >
touchend >
mouseover > mouseenter > mousemove > mousedown >
focus >
mouseup >
click >
pointerout > pointerleave
Specific order of events is not defined in the spec in this case – will vary between browsers...
only problem if handling both pointer events and mouse events (which is nonsensical)
192. /* Pointer Events extend Mouse Events
vs Touch Events and their new objects / TouchLists / Touches */
interface PointerEvent : MouseEvent {
readonly attribute long pointerId;
readonly attribute long width;
readonly attribute long height;
readonly attribute float pressure;
readonly attribute float tangentialPressure; /* Level 2 */
readonly attribute long tiltX;
readonly attribute long tiltY;
readonly attribute long twist; /* Level 2 */
readonly attribute DOMString pointerType;
readonly attribute boolean isPrimary;
}
193. handling mouse input is
exactly the same as traditional
mouse events
(only change pointer* instead of mouse* event names)
194. handling touch or stylus is
also exactly the same as
traditional mouse events
(mouse code can be adapted to touch/stylus quickly)
196. /* detecting pointer events support */
if ( window.PointerEvent ) {
/* some clever stuff here but this covers
touch, stylus, mouse, etc */
}
/* still listen to click for keyboard! */
198. /* detect maximum number of touch points */
if ( navigator.maxTouchPoints > 0 ) {
/* device with a touchscreen */
}
if ( navigator.maxTouchPoints > 1 ) {
/* multitouch-capable device */
}
"you can detect a touchscreen"
...but user may still use other input mechanisms
210. how can we make it feel
responsive like a native app?
211. we could try a similar
approach to touch events...
212. • double-up pointerup and click listeners?
• prevent code firing twice with preventDefault ?
won't work: preventDefault() stops mouse compatibility events, but
click is not considered mouse compatibility event
214. CSS property
what action should the browser handle?
touch-action: auto | none | [ pan-x || pan-y ] | manipulation
www.w3.org/TR/pointerevents/#the-touch-action-css-property
only determines default touch action, does not stop compatibility
mouse events nor click
215. Pointer Events Level 2
expanded set of values (useful for pull-to-refresh, carousels, etc)
touch-action: auto | none |
[ [ pan-x | pan-left | pan-right ] ||
[ pan-y | pan-up | pan-down ] ] |
manipulation
w3c.github.io/pointerevents/#the-touch-action-css-property
245. /* PointerEvents don't have the handy TouchList objects,
so we have to replicate something similar... */
ar points = [];
switch (e.type) {
case ' pointerdown ':
/* add to the array */
break;
case ' pointermove ':
/* update the relevant array entry's x and y */
break;
case ' pointerup ':
case ' pointercancel ':
/* remove the relevant array entry */
break;
}
247. /* like iOS/Safari, IE/Win has higher-level gestures ,
but these are not part of the W3C Pointer Events spec.
Replicate these from basic principles again... */
MSDN IE10 Developer Guide: Gesture object and events
263. adding jQuery PEP *
script src=https:code.jquery.compep0.4.1pep.jsscript
* need to use custom touch-action attribute, not CSS (yet) *
button touch-action=none ...div