Beyond smartphones and tablets, touchscreens are finding their way into laptops and even desktop computers. With hardware support for touch becoming increasingly ubiquitous, it's time to explore what new possibilities are available to developers. This session will cover the basics of handling touch events - from making sure simple single-tap interactions are as responsive as possible, all the way to examples of full multitouch, gesture-enabled elements.
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
32. • 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...
51. /* 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 */
52. /* common performance “trick”
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', ...);
...
}
/* if touch events are supported,
only listen to touchend, otherwise listen to click */
53. /* common performance “trick” (condensed) */
var clickEvent =
( 'ontouchstart' in window ? 'touchend' : 'click');
foo.addEventListener( clickEvent , ...);
/* if touch events are supported,
only listen to touchend, otherwise listen to click */
79. Android 6.1/Firefox + TalkBack – similar to touch
touchstart > mousedown > focus > touchend > mouseup > click
80. further scenarios?
• desktop with external touchscreen
• touchscreen laptop with non-touch second screen
• touchscreen laptop with trackpad/mouse
• ...and other permutations?
81. note on trackpad gestures
• trackpads that allow multi-finger gestures (e.g. recent MacBooks,
Magic Mouse/Trackpad, Windows precision trackpad, ASUS Smart
Gesture, Wacom Intuos Pro gestures etc) don't fire touch events /
expose touch points
• these gestures are handled directly by the OS/driver and don't reach
the browser as raw touches
• Wacom Intuos Pro touch input exposed as mouse to OS
• OS X/Safari 9.1+ does fire Apple's proprietary gesture* events (for
pinch-to-zoom, rotation)
86. /* 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 ... */
}
89. /* 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', ...);
...
}
90. /* 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
91. /* 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
134. /* Naive uses of Interaction Media Features */
@media (hover: hover) {
/* primary input has hover...so we can rely on it? */
}
@media (pointer: fine) {
/* primary input has fine pointer precision...
so make all buttons/controls small? */
}
/* hover and pointer only check "primary" input, but
what if there's a secondary input that lacks capabilities? */
135. /* Better uses of Interaction Media Features */
@media (any-hover: none) {
/* at least one input lacks hover capability...
don't rely on it or avoid altogether */
}
@media (any-pointer: coarse) {
/* at least one input has coarse pointer precision...
provide larger buttons/controls for touch */
}
/* test for presence of *any* "least capable"
input (primary or not) */
136. if in doubt, offer a way to switch interfaces...
or just always use a touch-optimised interface
154. 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
155. 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
156. changedTouches depending on event:
• for touchstart , all new touch points that became active
• for touchmove , all touch points that changed/moved since last event
• for touchend / touchcancel , touch points that were removed
(and are not active anymore at this point)
159. TouchList collections order
• order of individual Touch objects in a TouchList can change
• e.g. targetTouches[0] not guaranteed to always be the same finger
when dealing with multitouch
• not problematic for single-finger interactions, but use identifier
property for each Touch to explicitly track a particular touch point /
finger in multitouch
187. /* iOS/Safari/WebView has gesture events for size/rotation,
not part of the W3C Touch Events spec. */
gesturestart / gesturechange / gestureend
function(e) {
/* e.scale
e.rotation */
/* values can be plugged directly into
CSS transforms etc */
}
/* not supported in Chrome/Firefox/Opera */
iOS Developer Library - Safari Web Content Guide - Handling gesture events
190. /* with some trigonometry we can replicate
these from basic principles using coordinates
from two touch points */
var distance = Math.sqrt(Math.pow(...)+Math.pow(...));
var angle = Math.atan2(...);
209. Rick Byers - Paint (with rotationAngle and touchRadius)
210. /* 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 )
213. 3D Touch ≠ Force Touch
• Force Touch is Apple's proprietary extension to mouse events
• only aimed at force-enabled trackpads (new Apple models)
• new events: webkitmouseforcewillbegin , webkitmouseforcedown ,
webkitmouseforceup , webkitmouseforcechanged
• mouse events have additional webkitForce property
Safari Developer Library: Responding to Force Touch Events
224. ...and some new inputs (though currently mapped to mouse)
Building Xbox One Apps using HTML and JavaScript
YouTube: Xbox One Edge Browser sends Pointer Events
245. events fired on tap (IE10/IE11)
mousemove* >
pointerover > mouseover >
pointerenter > mouseenter >
pointerdown > mousedown >
gotpointercapture >
focus >
pointermove > mousemove >
pointerup > mouseup >
lostpointercapture >
pointerout > mouseout >
pointerleave > mouseleave >
click
mouse events fired “inline” with pointer events
(for a primary pointer, e.g. first finger on screen)
246. current IE10/11 quirk
...
pointerup > mouseup >
lostpointercapture >
pointerout > mouseout >
pointerleave > mouseleave >
click
the fact that click comes last is a current IE10/11 quirk – according
to spec it should come after pointerup > mouseup , and does already
when using touch-action
W3C Pointer Events WG mailing list - Jacob Rossi (Microsoft)
249. vendor-prefixed in IE10
MSPointerDown etc
navigator.msMaxTouchPoints
-ms-touch-action
unprefixed in IE11 (but prefixed versions still mapped for compatibility)
250. /* Pointer Events extend Mouse Events
vs Touch Events and their completely new objects/arrays */
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;
}
251. handling mouse input is
exactly the same as traditional
mouse event
(only change pointer* instead of mouse* event names)
253. /* detecting pointer events support */
if ( window.PointerEvent ) {
/* some clever stuff here but this covers
touch, stylus, mouse, etc */
}
/* still listen to click for keyboard! */
255. /* detect maximum number of touch points */
if ( navigator.maxTouchPoints > 0 ) {
/* device with a touchscreen */
}
if ( navigator.maxTouchPoints > 1 ) {
/* multitouch-capable device */
}
263. pointer / mouse events and delay
...
[300ms delay]
click
...
300ms delay just before click event
264. “how can we make it feel
responsive like a native app?”
265. we could try a similar
approach to touch events...
266. • 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
269. 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
270. 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
310. /* in IE11/Edge, pointerType returns a string
in IE10, the return type is long */
MSPOINTER_TYPE_TOUCH: 0x00000002
MSPOINTER_TYPE_PEN: 0x00000003
MSPOINTER_TYPE_MOUSE: 0x00000004
MSDN: IE Dev Center - API reference - pointerType property
312. /* PointerEvents don't have the handy TouchList objects,
so we have to replicate something similar... */
var 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;
}
315. simultaneous use of inputs is
hardware-dependent
(e.g. Surface 3 "palm blocking" prevents concurrent
touch/stylus/mouse, but not
touch/external mouse/external stylus)
317. /* 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
330. • touch events have implicit capture: once you start a touch movement
on an element, events keep firing to the element even when moving
outside the element's boundaries
• pointer events behave like mouse events: only fire events to an
element while pointer (e.g. finger on touchscreen) inside element, but
you can explicitly capture pointers
331. /* events related to pointer capture */
gotpointercapture / lostpointercapture
/* example of how to capture a pointer explicitly */
element.addEventListener('pointerdown', function(e) {
this. setPointerCapture(e.pointerId) ;
}, false }
/* capture automatically released on pointerup / pointercancel
or explicitly with releasePointerCapture() */
patrickhlauke.github.io/touch/tests/pointercapture.html
332. setPointerCapture also
works for mouse input
can be used instead of traditional "bind mousemove to
document / body on mousedown " approach
351. /* adding jQuery PEP */
<script src="https://code.jquery.com/pep/0.4.1/pep.js"></script>
/* need to use custom touch-action attribute, not CSS (yet) */
<button touch-action="none" >...</div>
362. /* Hammer's high-level events example */
var element = document.getElementById('test_el');
var hammertime = new Hammer(element);
hammertime.on("swipe",
function(event) {
/* handle horizontal swipes */
});
378. • Matt Gaunt – Touch Feedback for Mobile Sites
• Jonathan Stark – FastActive
• Stephen Woods – HTML5 Touch Interfaces
• YouTube: Stephen Woods – Responsive HTML5 Touch Interfaces
• Chris Wilson + Paul Kinlan – Touch And Mouse: Together Again For
The First Time
• Ryan Fioravanti – Creating Fast Buttons for Mobile Web Applications
• Boris Smus – Multi-touch Web Development
• Boris Smus – Generalized input on the cross-device web
• Boris Smus – Interactive touch laptop experiments
379. • Rick Byers + Boris Smus (Google I/O) – Point, Click, Tap, Touch -
Building Multi-Device Web Interfaces
• Grant Goodale – Touch Events
• W3C – Touch Events Extensions
• Mozilla Developer Network – Touch Events
• WebPlatform.org – Pointer Events
• Rick Byers – The best way to avoid the dreaded 300ms click delay is
to disable double-tap zoom
• Chromium Issue 152149: All touch-event related APIs should exist if
touch support is enabled at runtime
380. • Tim Kadlec – Avoiding the 300ms Click Delay, Accessibly
• David Rousset - Unifying touch and mouse [...]
• Microsoft – Pointer events updates (differences between IE10-IE11)
• Patrick H. Lauke – Webseiten zum Anfassen
• Patrick H. Lauke – Drei unter einem Dach: Pointer-Events für Maus,
Stylus und Touchscreen
• Patrick H. Lauke – Erweiterte Interaktionsmöglichkeiten mit
Touchscreens
• Patrick H. Lauke – Make your site work on touch devices
• Stu Cox – You can't detect a touchscreen
381. • Microsoft – Hover touch support (IE10/IE11)
• W3C Media Queries Level 4 – pointer
• Stu Cox – The Good & Bad of Level 4 Media Queries
• Peter-Paul Koch – Touch table
• Peter-Paul Koch – Preventing the touch default
• Peter-Paul Koch – Mouse event bubbling in iOS
• YouTube: Edge Conference (Feb 2013 London) – Panel: Input
• Edge Conference (Mar 2014 London) – Panel: Pointers and Interactions
• Trent Walton – Device-Agnostic
382. • Stu Cox – The Golden Pattern for Handling Touch Input
• Matt Gaunt – ‘Focusing’ on the Web Today
• Mobiscroll – Working with touch events
• Peter-Paul Koch – The iOS event cascade and innerHTML
• Patrick H. Lauke – Make your site work on touch devices
• Scott Jehl (Filament Group) – Tappy: A custom tap event handler
• Yehuda Katz – Touch events on the web are fundamentally unfinished
383. • Andrea Giammarchi – PointerEvents No More
• YouTube: Matt Gaunt (Google) - Touch in a Web App? No Problem
• Luke Wroblewski – How to Communicate Hidden Gestures
• David Washington - Designing custom touch interactions
• David Washington - Building pull-to-refresh
• Andy Peatling - JavaScript Pull to Refresh for the Web
• Tilo Mitra – The State of Gestures
• YouTube: Tilo Mitra (YUI) – The State of Gestures
384. • Rob Larsen - The Uncertain Web: Pointer Event Polyfill and Chrome
Fragmentation
• Detlev Fisher - Implications of new input modes (touch, speech,
gestures) for the Web Content Accessibility Guidelines
• Ralph Thomas - Towards declarative touch interactions
• Windows Dev Center: Windows desktop applications > Guidelines >
Interaction (touch, keyboard, mouse, pen)
• Microsoft Open Technologies - jQuery Adopts Pointer Events
385. • jQuery blog - Getting on Point
• IEBlog - Pointer Events W3C Recommendation, Interoperable Touch,
and Removing the Dreaded 300ms Tap Delay
• Microsoft Open Technologies - Pointer Events is now a W3C Standard
• Patrick H. Lauke (The Paciello Group) - Pointer Events advance to W3C
Recommendation
• Jacob Rossi - The Input Shouldn't Matter
• hacks.mozilla.org - Pointer Events now in Firefox Nightly
386. • Rick Byers – Interoperability Case Studies at BlinkOn 5 (touch-action)
• Mozilla Developer Network – Pointer Events
• Christian Saylor – A Touch of Brilliance: Why 3D Touch Matters
• Lukas Mathis – Usability on Mobile Is Getting Worse
• Rocket Insights – Initial thoughts on 3D Touch
• Wiser Coder – Disable “pull to refresh” in Chrome for Android
387. • Google Developers / Web Fundamentals: Add touch to your site
• Alex Gibson – Different ways to trigger touchcancel in mobile
browsers
• BBC Global Experience Language: How to design for touch
• Google BlinkOn 5: Lightning talks / Mustaq Ahmed – Pointer Events
in Chrome implementation update
• A Book Apart: Josh Clark – Designing for Touch
388. • Ruadhán O'Donoghue – The HTML5 Pointer Events API: Combining
touch, mouse, and pen
• Jordan Staniscia – Hover is dead. Long live hover.
• Jason Grigsby – Four Truths About Input
• Jason Grigsby – Adapting to Input
• David Corbacho – Debouncing and Throttling Explained
• YouTube: Pre-Touch Sensing for Mobile Interaction (Microsoft)
389. • YouTube: HTML5DevConf: Jacob Rossi, "Pointer Events, Panning &
Zooming, and Gestures"
• YouTube: Jacob Rossi, "Pointing Forward" at W3Conf 2013
• YouTube: Tim Park: Pointing Forward (updated) – JSConf.Asia 2013
• Flickity – touch, responsive, flickable carousels