Getting touchy - an introduction to touch and pointer events / Workshop / JavaScript Days / Berlin 25.09.2013

Patrick Lauke
Patrick LaukePrincipal Accessibility Specialist
getting touchy
AN INTRODUCTION TO TOUCH AND POINTER EVENTS
Patrick H. Lauke / JavaScript Days / Berlin / 25 September 2013
1. introduction
2. touch events
3. break
4. pointer events
5. debugging/testing
6. conclusion
patrickhlauke.github.io/touch
how can I make my website
work on touch devices?
you don't need touch events
browsers emulate regular mouse events
patrickhlauke.github.io/touch/tests/event-listener_mouse-only.html
patrickhlauke.github.io/touch/tests/event-listener_mouse-only.html
mouseover > mousemove* > mousedown >
(focus) > mouseup > click
*only a single “sacrificial” event is fired
on first tap
mouseover > mousemove > mousedown >
(focus) > mouseup > click
subsequent taps
mousemove > mousedown > (focus) >
mouseup > click
tapping away
mouseout > (blur)
focus/blur only on focusable elements in Opera Mobile and Firefox
mouseout not on iOS Safari and embedded WebView (e.g. iOS Chrome)
emulation works but is
limiting/problematic
(more on that in a minute)
1. delayed event dispatch
2. mouse-specific interfaces
3. mousemove doesn't track
1. delayed event dispatch
2. mouse-specific interfaces
3. mousemove doesn't track
patrickhlauke.github.io/touch/tests/event-listener_show-delay.html
patrickhlauke.github.io/touch/tests/event-listener_show-delay.html
1. delayed event dispatch
2. mouse-specific interfaces
3. mousemove doesn't track
patrickhlauke.github.io/touch/css-dropdown/mouse-only.html
1. delayed event dispatch
2. mouse-specific interfaces
3. mousemove doesn't track
patrickhlauke.github.io/touch/particle/2
patrickhlauke.github.io/touch/particle/2
(bug in iOS7: moving finger does seem to scroll and fire multiple mousemove events?!)
“we need to go deeper...”
touch events
introduced in iOS 2.0, adopted in Chrome/Firefox/Opera
www.w3.org/TR/touch-events
touchstart
touchmove
touchend
touchcancel
touchenter
touchleave
patrickhlauke.github.io/touch/tests/event-listener_all-no-timings.html
patrickhlauke.github.io/touch/tests/event-listener_all-no-timings.html
touchstart > [touchmove]+ > touchend >
mouseover > mousemove > mousedown >
(focus) > mouseup > click
on first tap
touchstart > [touchmove]+ > touchend > mouseover >
mousemove > mousedown > (focus) > mouseup > click
subsequent taps
touchstart > [touchmove]+ > touchend > mousemove >
mousedown > (focus) > mouseup > click
tapping away
mouseout > (blur)
too many touchmove events abort the tap (after touchend)
not all browsers consistently send the touchmove
some browsers outright weird...
Browser/Android 4.2.2
(AppleWebKit/534.30)
mouseover > mousemove > touchstart > touchend > mousedown >
mouseup > click
Browser/Blackberry PlayBook 2.0
(AppleWebKit/536.2)
touchstart > mouseover > mousemove > mousedown > touchend >
mouseup > click
touch events
vs
limitations/problems of
mouse event emulation
1. delayed event dispatch
2. mouse-specific interfaces
3. mousemove doesn't track
1. delayed event dispatch
2. mouse-specific interfaces
3. mousemove doesn't track
patrickhlauke.github.io/touch/tests/event-listener_show-delay.html
patrickhlauke.github.io/touch/tests/event-listener_show-delay.html
patrickhlauke.github.io/touch/tests/event-listener.html
patrickhlauke.github.io/touch/tests/event-listener.html
“how can we make it feel
responsive like a native app?”
simple feature detection for
touch events
if ('ontouchstart' in window) {
/* some clever stuff here */
}
/* common performance “trick” */
var clickEvent = ('ontouchstart' in window ?
'touchend' : 'click');
blah.addEventListener(clickEvent,
function() { ... }, false);
don't make it touch-exclusive
hacks.mozilla.org/2013/04/detecting-touch...
if ('ontouchstart' in window) {
/* browser supports touch events
but user is not necessarily
using touch (exclusively) */
}
hybrid devices
touch + mouse + keyboard
patrickhlauke.github.io/touch/tests/event-listener_show-delay-naive-event-fix.html
bugzilla.mozilla.org/show_bug.cgi?id=888304
Getting touchy - an introduction to touch and pointer events / Workshop / JavaScript Days / Berlin 25.09.2013
Android + mouse – behaves like touch
touchstart > touchend > mouseover > mousemove > mousedown > mouseup > click
Blackberry PlayBook 2.0 + mouse – like desktop mouse
mouseover > mousedown > mousemove > mouseup > click
Android + keyboard – like desktop keyboard
focus > click
VoiceOver enables keyboard access on iOS
iOS + keyboard – similar to touch
focus > touchstart > touchend > mouseover > mousemove > mousedown
blur > mouseup > click
iOS + VoiceOver – similar to touch
focus > touchstart > touchend > mouseover > mousemove > mousedown
blur > mouseup > click
Android + TalkBack – keyboard/mouse hybrid
focus > blur > mousedown > mouseup > click > focus(?)
mouse or touch
vs
mouse and touch and
keyboard
/* doubled-up event listeners */
foo.addEventListener('touchstart',
someFunction, false);
foo.addEventListener('click',
someFunction, false);
/* doubled-up event listeners */
foo.addEventListener('touchstart',
function(e) {
/* prevent delay + mouse events */
e.preventDefault();
someFunction();
/* or even e.target.click(); */
}, false);
foo.addEventListener('click',
someFunction, false);
github.com/ftlabs/fastclick
preventDefault
kills scrolling, long-press,
pinch/zoom
Getting touchy - an introduction to touch and pointer events / Workshop / JavaScript Days / Berlin 25.09.2013
browsers working to remove
delay when possible
e.g. Chrome on desktop, Chrome/Firefox on Android
patrickhlauke.github.io/touch/tests/event-listener_user-scalable-no.html
patrickhlauke.github.io/touch/tests/event-listener_user-scalable-no.html
patrickhlauke.github.io/touch/tests/event-listener_minimum-maximum-scale.html
Getting touchy - an introduction to touch and pointer events / Workshop / JavaScript Days / Berlin 25.09.2013
patrickhlauke.github.io/touch/tests/event-listener_user-scalable-no.html
patrickhlauke.github.io/touch/tests/event-listener_user-scalable-no.html
patrickhlauke.github.io/touch/tests/event-listener_minimum-maximum-scale.html
patrickhlauke.github.io/touch/tests/event-listener_user-scalable-no.html
1. delayed event dispatch
2. mouse-specific interfaces
3. mousemove doesn't track
patrickhlauke.github.io/touch/css-dropdown/mouse-only.html
no isolated hover (or focus)
on touch devices*
* iOS fakes it, Samsung Galaxy S4 + stylus, ...
patrickhlauke.github.io/touch/css-dropdown/mouse-only.html
patrickhlauke.github.io/touch/css-dropdown/mouse-only.html
http://developer.apple.com/library/IOS/...
Modernizr issue 869: Detecting a mouse user
www.stucox.com/blog/you-cant-detect-a-touchscreen
avoid hover-based interfaces?
complement for keyboard / touch!
patrickhlauke.github.io/touch/css-dropdown/mouse-keyboard.html
patrickhlauke.github.io/touch/css-dropdown/mouse-keyboard.html
patrickhlauke.github.io/touch/css-dropdown/mouse-keyboard-touch.html
1. delayed event dispatch
2. mouse-specific interfaces
3. mousemove doesn't track
patrickhlauke.github.io/touch/particle/2
patrickhlauke.github.io/touch/particle/2
(bug in iOS7: moving finger does seem to scroll and fire multiple mousemove events?!)
touchstart > [touchmove]+ > touchend >
mouseover > mousemove* > mousedown >
(focus) > mouseup > click
*mouse event emulation fires only a single mousemove
doubling up handling of
mousemove and touchmove
var posX, posY;
...
function positionHandler(e) {
posX = e.clientX;
posY = e.clientY;
}
...
canvas.addEventListener('mousemove',
positionHandler, false);
var posX, posY;
...
function positionHandler(e) {
/* handle both mouse and touch? */
}
...
canvas.addEventListener('mousemove',
positionHandler, false);
canvas.addEventListener('touchmove',
positionHandler, false);
interface MouseEvent : UIEvent {
readonly attribute long screenX;
readonly attribute long screenY;
readonly attribute long clientX;
readonly attribute long clientY;
readonly attribute boolean ctrlKey;
readonly attribute boolean shiftKey;
readonly attribute boolean altKey;
readonly attribute boolean metaKey;
readonly attribute unsigned short button;
readonly attribute EventTarget relatedTarget;
void initMouseEvent(...);
};
www.w3.org/TR/DOM-Level-2-Events/events.html#Events-MouseEvent
interface TouchEvent : UIEvent {
readonly attribute TouchList touches;
readonly attribute TouchList targetTouches;
readonly attribute TouchList changedTouches;
readonly attribute boolean altKey;
readonly attribute boolean metaKey;
readonly attribute boolean ctrlKey;
readonly attribute boolean shiftKey;
};
www.w3.org/TR/touch-events/#touchevent-interface
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
var posX, posY;
...
function positionHandler(e) {
if ((e.clientX)&&(e.clientY)) {
posX = e.clientX;
posY = e.clientY;
} else if (e.targetTouches) {
posX = e.targetTouches[0].clientX;
posY = e.targetTouches[0].clientY;
e.preventDefault();
}
}
...
canvas.addEventListener('mousemove',
positionHandler, false );
canvas.addEventListener('touchmove',
positionHandler, false );
patrickhlauke.github.io/touch/particle/3
patrickhlauke.github.io/touch/particle/4
www.splintered.co.uk/experiments/archives/paranoid_0.5
tracking finger movement
over time ... swipe gestures
patrickhlauke.github.io/touch/swipe
patrickhlauke.github.io/touch/swipe
patrickhlauke.github.io/touch/picture-slider
don't forget mouse/keyboard !
bradfrostweb.com/demo/mobile-first
touchmove fires...a lot!
patrickhlauke.github.io/touch/touch-limit
heavy javascript on
requestAnimationFrame
setInterval
why stop at a single point?
multitouch support
interface TouchEvent : UIEvent {
readonly attribute TouchList touches;
readonly attribute TouchList targetTouches;
readonly attribute TouchList changedTouches;
readonly attribute boolean altKey;
readonly attribute boolean metaKey;
readonly attribute boolean ctrlKey;
readonly attribute boolean shiftKey;
};
www.w3.org/TR/touch-events/#touchevent-interface
for (i=0; i<e.targetTouches.length; i++) {
...
posX = e.targetTouches[i].clientX;
posY = e.targetTouches[i].clientY;
...
}
patrickhlauke.github.io/touch/tracker/multi-touch-tracker.html
iOS/iPad even preventDefault()
can't override 4-finger gestures
iOS7/Safari even preventDefault()
can't override back/forward swipe gestures
multitouch gestures
/* iOS/Safari has gesture events for size/rotation,
not supported in Chrome/Firefox/Opera,
not part of the W3C Touch Events spec. */
gesturestart, gesturechange, gestureend
e.scale, e.rotation
patrickhlauke.github.io/touch/iosgestures
patrickhlauke.github.io/touch/iosgestures/image.html
/* with some trigonometry we can replicate these
from basic principles. */
var distance = Math.sqrt(Math.pow(...)+Math.pow(...));
var angle = Math.atan2(...);
patrickhlauke.github.io/touch/pinch-zoom-rotate
shinydemos.com/picture-organizer
touch events and IE10
blogs.msdn.com/...
www.w3.org/TR/pointerevents
not just some “not invented here”
new approach for IE10+
html5labs.interoperabilitybridges.com/prototypes/...
https://code.google.com/p/chromium/issues/detail?id=162757
https://bugzilla.mozilla.org/show_bug.cgi?id=822898
...and of course Apple is ignoring it...
patrickhlauke.github.io/touch/tests/event-listener_all-no-timings.html
patrickhlauke.github.io/touch/tests/event-listener_all-no-timings.html
pointerover > mouseover >
pointerdown > mousedown >
pointermove > mousemove >
(focus) >
pointerup > mouseup >
pointerout > mouseout >
click
mouse events fired “inline” with pointer events
(for the primary contact, e.g. first finger on screen)
pointerenter
pointerleave
gotpointercapture
lostpointercapture
interface MouseEvent : UIEvent {
readonly attribute long screenX;
readonly attribute long screenY;
readonly attribute long clientX;
readonly attribute long clientY;
readonly attribute boolean ctrlKey;
readonly attribute boolean shiftKey;
readonly attribute boolean altKey;
readonly attribute boolean metaKey;
readonly attribute unsigned short button;
readonly attribute EventTarget relatedTarget;
void initMouseEvent(...);
};
www.w3.org/TR/DOM-Level-2-Events/events.html#Events-MouseEvent
/* 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 long tiltX;
readonly attribute long tiltY;
readonly attribute DOMString pointerType;
readonly attribute boolean isPrimary;
};
www.w3.org/TR/pointerevents/#pointerevent-interface
simple feature detection for
pointer events
if (navigator.pointerEnabled) {
/* some clever stuff here
but this covers touch,
stylus, mouse, etc */
}
/* still listen to click for keyboard! */
if (navigator.maxTouchPoints > 1) {
/* multitouch-capable device */
}
patrickhlauke.github.io/touch/tests/pointer-multitouch-detect.html
pointer events
vs
limitations/problems of
mouse event emulation
1. delayed event dispatch
2. mouse-specific interfaces
3. mousemove doesn't track
1. delayed event dispatch
2. mouse-specific interfaces
3. mousemove doesn't track
patrickhlauke.github.io/touch/tests/event-listener_show-delay.html
patrickhlauke.github.io/touch/tests/event-listener_show-delay.html
patrickhlauke.github.io/touch/tests/event-listener.html
patrickhlauke.github.io/touch/tests/event-listener.html
patrickhlauke.github.io/touch/tests/event-listener.html
“how can we make it feel
responsive like a native app?”
preventDefault() won't work
(but you can prevent most mouse compatibility events by
cancelling pointerdown)
touch-action: auto|none|[pan-x][pan-y]
www.w3.org/TR/pointerevents/#the-touch-action-css-property
only prevents default touch action (e.g. double-tap to zoom)
does not stop synthetic mouse events nor click
touch-action:none
kills scrolling, long-press,
pinch/zoom
touch-action:none
http://patrickhlauke.github.io/touch/tests/event-listener_touch-action-none.html
http://patrickhlauke.github.io/touch/tests/event-listener_touch-action-none.html
1. delayed event dispatch
2. mouse-specific interfaces
3. mousemove doesn't track
msdn.microsoft.com/en-us/library/ie/dn265029(v=vs.85).aspx
msdn.microsoft.com/en-us/library/ie/jj152135(v=vs.85).aspx
patrickhlauke.github.io/touch/css-dropdown/mouse-only-aria-haspopup.html
channel9.msdn.com/Blogs/IE/IE11-Using-Hover-Menus-with-Touch
1. delayed event dispatch
2. mouse-specific interfaces
3. mousemove doesn't track
patrickhlauke.github.io/touch/particle/2
touch-action:none
patrickhlauke.github.io/touch/particle/2a
patrickhlauke.github.io/touch/tracker/mouse-tracker_touch-action-none.html
/* PointerEvents don't have the handy touch arrays,
so we have to replicate something similar... */
/* PointerEvents don't have the handy touch arrays,
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':
/* remove the relevant array entry */
break;
}
patrickhlauke.github.io/touch/tracker/multi-touch-tracker-pointer.html
/* like iOS/Safari, IE10/Win has higher-level gestures,
but these are not part of the W3C Pointer Events spec.
Replicate these from basic principles again? */
www.exploretouch.ie/behind-the-scenes
vendor-prefixed in IE10
(and case-sensitive?!)
MSPointerDown
MSPointerMove
MSPointerUp
navigator.msPointerEnabled
navigator.msMaxTouchPoints
-ms-touch-action
unprefixed in IE11
polyfills for pointer events
(code for tomorrow, today)
handjs.codeplex.com
www.catuhe.com/msdn/handjs
github.com/Polymer/PointerEvents
www.polymer-project.org
utility libraries
(because life is too short to hand-code gesture support etc)
eightmedia.github.io/hammer.js
jQuery Mobile? Sencha Touch? …
check for support of IE10+ and “this is a touch device” assumptions
debugging/testing
Issue 181204: Emulate touch events - event order different from real devices
developers.google.com/chrome-developer-tools/docs/console#monitoring_events
Bug 861876 - [...] multiple mousemoves being fired
Getting touchy - an introduction to touch and pointer events / Workshop / JavaScript Days / Berlin 25.09.2013
further reading...
webkrauts.de/artikel/2012/einfuehrung-touch-events
www.html5rocks.com/en/mobile/touchandmouse
blogs.msdn.com/b/davrous/.../handling-touch-in-your-html5-apps...
www.slideshare.net/ysaw/html5-touch-interfaces-sxsw-extended-version
youtube.com/watch?v=AZKpByV5764
danke
@patrick_h_lauke
github.com/patrickhlauke/touch
slideshare.net/redux
paciellogroup.com
splintered.co.uk
1 von 184

Más contenido relacionado

Similar a Getting touchy - an introduction to touch and pointer events / Workshop / JavaScript Days / Berlin 25.09.2013

ToucheventsTouchevents
Toucheventsguest2f8eaf
1.2K views49 Folien
The touch eventsThe touch events
The touch eventsPeter-Paul Koch
4.4K views49 Folien

Similar a Getting touchy - an introduction to touch and pointer events / Workshop / JavaScript Days / Berlin 25.09.2013(20)

Más de Patrick Lauke(20)

Getting touchy - an introduction to touch and pointer events / Workshop / JavaScript Days / Berlin 25.09.2013