Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
gettingtouchy
AN INTRODUCTION TO TOUCH AND POINTER EVENTS
Patrick H. Lauke / Web Rebels / Oslo / 22 May 2014
patrickhlauke.github.io/touch
Touch/pointer events test results
“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
compatibility mouse events
(mouseenter) > mouseover > mousemove* > mousedown >
(focus) > mouseup > click
* only a single “...
on first tap
(mouseenter) > mouseover > mousemove >
mousedown > (focus) > mouseup > click
subsequent taps
mousemove > mous...
emulation works,
but is limiting/problematic
1.  delayed event dispatch
2.  mousemove doesn't track
1.  delayed event dispatch
2.  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.  mousemove doesn't track
patrickhlauke.github.io/touch/particle/2
patrickhlauke.github.io/touch/particle/2
(iOS7 bug: moving finger fires mousemove on scroll)
“we need to go deeper...”
touch events
introduced by Apple, 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
Bug 128534 - 'mouseenter' mouse compat event not fi...
events fired on tap
touchstart > [touchmove]+ > touchend >
(mouseenter) > mouseover > mousemove > mousedown >
(focus) > mo...
on first tap
touchstart > [touchmove]+ > touchend >
(mouseenter) > mouseover > mousemove > mousedown >
(focus) > mouseup >...
•  too many touchmove events prevent mouse compatibility events
after touchend (not considered a "clean" tap)
•  too many ...
Browser/Android 4.3
(AppleWebKit/534.30)
mouseover > mousemove > touchstart > touchend >
mousedown > mouseup > click
Brows...
Touch/pointer events test results
touch events
vs
limitations/problems
1.  delayed event dispatch
2.  mousemove doesn't track
1.  delayed event dispatch
2.  mousemove doesn't track
patrickhlauke.github.io/touch/tests/event-listener_show-delay.html
why the delay?
double-tap to zoom
(mostly anyway)
what if browsers didn't wait?
Puffin/Android double-tap zooms and fires mouse events + click
(also, doesn't support touch events)
Try it out in Chrome? chrome://flags/
when does the delay happen?
patrickhlauke.github.io/touch/tests/event-listener.html
touch / mouse events delay
touchstart > [touchmove]+ > touchend >
[300ms delay]
(mouseenter) > mouseover > mousemove > mou...
“how can we make it feel
responsive like a native app?”
react to events fired before the
300ms delay...
touchstart for an “immediate”
control
(fire/jump button on a game)
touchend for a control that
fires after finger lifted
interlude: simple feature
detection for touch events
/* feature detection for touch events */
if ( 'ontouchstart' in window ) {
/* some clever stuff here */
}
/* older browser...
/* common performance “trick” */
var clickEvent =
( 'ontouchstart' in window ? 'touchend' : 'click' );
blah.addEventListen...
don't make it touch-exclusive
/* common performance “trick” */
var clickEvent =
( 'ontouchstart' in window ? 'touchend' : 'click');
...
/* if touch even...
hybrid devices
touch + mouse + keyboard
Android + mouse – behaves like touch
touchstart > touchend > mouseover > mousemove > mousedown >
(focus) > mouseup > click
Blackberry PlayBook 2.0 + mouse - like desktop
mouse mouseover > mousedown > mousemove > mouseup > click
Android + keyboard – like desktop keyboard
focus > click
iOS + VoiceOver (with/without keyboard) – similar to touch
focus > touchstart > touchend > (mouseenter) > mouseover >
mous...
Android + TalkBack – keyboard/mouse hybrid
focus > blur > mousedown > mouseup > click > focus(?)
hacks.mozilla.org - Detecting touch [...]
/* feature detection for touch events */
if ('ontouchstart' in window) {
/* browser supports touch events but user is
not ...
touch or mouse or keyboard
touch and mouse and keyboard
/* doubled-up event listeners */
foo.addEventListener(' touchend ', someFunction, false);
foo.addEventListener(' click ', ...
/* prevent delay + mouse events */
foo.addEventListener(' touchstart ', function(e) {
e.preventDefault();
}, false);
/* do...
preventDefault() kills
scrolling, pinch/zoom, etc
apply preventDefault()
carefully
(just on buttons/links, not entire page)
github.com/ftlabs/fastclick
browsers working to remove
double-tap to zoom delay
(when page not zoomable)
<meta name="viewport" content="user-scalable=no">
patrickhlauke.github.io/touch/tests/event-listener_user-scalable-no.html
<meta name="viewport" content="user-scalable=no">
patrickhlauke.github.io/touch/tests/event-listener_user-scalable-no.html
... content="minimum-scale=1, maximum-scale=1"
patrickhlauke.github.io/touch/tests/event-listener_minimum-maximum-scale.ht...
... content="minimum-scale=1, maximum-scale=1"
patrickhlauke.github.io/touch/tests/event-listener_minimum-maximum-scale.ht...
Bug 922896 - Optimizations to remove 300ms [...] delay
[RESOLVED - FIXED]
what about accessibility?
patrickhlauke.github.io/touch/tests/event-listener_user-scalable-no.html
Chrome 32+ / Android: ... content="width=device-width"
updates.html5rocks.com/2013/12/300ms-tap-delay-gone-away
Bug 941995 - Remove 300ms [...] on "responsive" pages
patrickhlauke.github.io/touch/tests/event-listener_user-scalable-no.html
iOS/Safari designed themselves into a corner: “double-tap to scroll”
bugs.webkit.org/show_bug.cgi?id=122212
1.  delayed event dispatch
2.  mousemove doesn't track
patrickhlauke.github.io/touch/particle/2
patrickhlauke.github.io/touch/particle/2
(iOS7 bug: moving finger fires mousemove on scroll)
events fired on tap
touchstart > [touchmove]+ > touchend >
(mouseenter) > mouseover >
mousemove* > mousedown > (focus) >
m...
doubling up handling of
mousemove and touchmove
var posX, posY;
...
function positionHandler(e) {
posX = e.clientX ;
posY = e.clientY ;
}
...
canvas.addEventListener(' mo...
var posX, posY;
...
function positionHandler(e) {
/* handle both mouse and touch */
}
...
canvas.addEventListener(' mousem...
interface MouseEvent : UIEvent {
readonly attribute long screenX ;
readonly attribute long screenY ;
readonly attribute lo...
partial interface MouseEvent {
readonly attribute double screenX;
readonly attribute double screenY;
readonly attribute do...
interface TouchEvent : UIEvent {
readonly attribute TouchList touches ;
readonly attribute TouchList targetTouches ;
reado...
interface Touch {
readonly attribute long identifier;
readonly attribute EventTarget target;
readonly attribute long scree...
touches
all touch points on screen
targetTouches
all touch points that started on the element
changedTouches
touch points ...
patrickhlauke.github.io/touch/touchlist-objects
var posX, posY;
...
function positionHandler(e) {
if ((e.clientX)&&(e.clientY)) {
posX = e.clientX; posY = e.clientY;
} el...
patrickhlauke.github.io/touch/particle/3
tracking finger movement over
time ... swipe gestures
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!
do absolute minimum on each
touchmove
(usually: store coordinates)
heavy JavaScript on
setInterval or
requestAnimationFrame
patrickhlauke.github.io/touch/touch-limit
why stop at a single point?
multitouch support
interface TouchEvent : UIEvent {
readonly attribute TouchList touches ;
readonly attribute TouchList targetTouches ;
reado...
/* iterate over touch array */
for (i=0; i< e.targetTouches .length; i++) {
...
posX = e.targetTouches[i].clientX ;
posY =...
patrickhlauke.github.io/touch/tracker/multi-touch-tracker.html
iOS/iPad preventDefault()
can't override 4-finger
gestures
iOS7/Safari preventDefault()
can't override back/forward
swipe gestures
multitouch gestures
/* iOS/Safari/WebView has gesture events for size/rotation,
not part of the W3C Touch Events spec. */
gesturestart / gestu...
/* with some trigonometry we can replicate
these from basic principles. */
var distance = Math.sqrt(Math.pow(...)+Math.pow...
patrickhlauke.github.io/touch/picture-organiser
not all old/cheap devices/OSs
support multitouch!
HTC Hero – Android 2.1
LG Optimus 2X – Android 2.3.7
ZTE Open – Firefox OS 1.1
what about
Internet Explorer?
up to IE9 (Win7 / WinPhone7.5)
only mouse events
in IE10 Microsoft introduced
Pointer Events
David Rousset - Unifying touch and mouse [...]
not just some
“not invented here”
technology
Pointer Events - W3C Candidate Recommendation 09 May 2013
Pointer Events - W3C Editor's Draft 14 May 2014
html5labs.interoperabilitybridges.com/prototypes/...
Issue 162757: Implement pointer events in Chrome behind experimental flag
Bug 822898 - Implement pointer events
...what about Apple?
Bug 105463 - Implement pointer events RESOLVED WONTFIX
patrickhlauke.github.io/touch/tests/event-listener_all-no-timings.html
patrickhlauke.github.io/touch/tests/event-listener_all-no-timings.html
events fired on tap
mousemove* >
pointerover > mouseover >
pointerenter > mouseenter >
pointerdown > mousedown >
pointermo...
vendor-prefixed in IE10
MSPointerDown etc
navigator.msMaxTouchPoints
-ms-touch-action
unprefixed in IE11 (but prefixed ver...
/* Pointer Events extend Mouse Events
vs Touch Events and their completely new objects/arrays */
interface PointerEvent : ...
simple feature detection for
pointer events
/* detecting pointer events support */
if ( window.PointerEvent ) {
/* some clever stuff here but this covers
touch, stylu...
/* detect maximum number of touch points */
if ( navigator.maxTouchPoints > 0 ) {
/* device with a touchscreen */
}
if ( n...
are pointer events better?
no need for separate mouse or
touch event listeners
/* touch events: separate handling */
foo.addEventListener('touchmove', ... , false);
foo.addEventListener('mousemove', .....
no need for separate mouse or
touch code to get x / y coords
/* Pointer Events extend Mouse Events */
foo.addEventListener(' pointermove ', function(e) {
...
posX = e.clientX ;
posY =...
but you can distinguish mouse
or touch or stylus if needed
foo.addEventListener('pointermove', function(e) {
...
switch( e.pointerType ) {
case ' mouse ':
...
break;
case ' pen ':
....
pointer events
vs
limitations/problems of mouse
event emulation
1.  delayed event dispatch
2.  mousemove doesn't track
1.  delayed event dispatch
2.  mousemove doesn't track
patrickhlauke.github.io/touch/tests/event-listener_show-delay.html
(IE/Win8 has double-tap to zoom, so problem on desktop ...
patrickhlauke.github.io/touch/tests/event-listener.html
patrickhlauke.github.io/touch/tests/event-listener.html
pointer / mouse events and delay
mousemove >
pointerover > mouseover >
pointerenter > mouseenter >
pointerdown > mousedown...
“how can we make it feel
responsive like a native app?”
we could try a similar
approach to touch events...
•  double-up listeners - pointerup and click
•  prevent code firing twice - preventDefault
preventDefault() on pointerdown...
patrickhlauke.github.io/touch/tests/event-listener.html
touch-action
CSS property
touch-action: auto | none | [ pan-x || pan-y ] | manipulation
www.w3.org/TR/pointerevents/#the-touch-action-c...
touch-action:none kills
scrolling, long-press,
pinch/zoom
touch-action:manipulation
patrickhlauke.github.io/touch/tests/event-listener_touch[...]
Bug 979345 - Implement touch-action:manipulation [...]
Issue 349016: Add support for touch-action:manipulation
Bug 133114 - Implement " touch-action:manipulation " [...]
1.  delayed event dispatch
2.  mousemove doesn't track
patrickhlauke.github.io/touch/particle/2
touch-action:none
patrickhlauke.github.io/touch/particle/2a
what about multitouch?
/* PointerEvents don't have the handy TouchList objects,
so we have to replicate something similar... */
var points = [];
...
patrickhlauke.github.io/touch/tracker/multi-touch-tracker-
pointer.html
(note multiple isPrimary pointers)
/* like iOS/Safari, IE/Win has higher-level gestures ,
but these are not part of the W3C Pointer Events spec.
Replicate th...
/* advanced topic: pointer capture */
gotpointercapture / lostpointercapture
element.setPointerCapture(pointerId)
patrickh...
what about backwards-
compatibility?
touchstart > [touchmove]+ > touchend >
[300ms delay] >
mouseover > mousemove > mousedown > mouseup > click
vs
pointerover ...
W3C Touch Events Community Group
/* cover all cases (hat-tip Stu Cox) */
if ('onpointerdown' in window) {
/* bind to Pointer Events: pointerdown, pointerup...
polyfills for pointer events
(code for tomorrow, today)
HandJS
www.catuhe.com/msdn/handjs/
Polymer
GitHub - Polymer/PointerEvents
/* Polymer's PointerEvents are not fired unless
an element has a (custom) touch-action attribute */
<div id="foo" touch-ac...
utility libraries
(because life is too short to hand-code gesture support)
Hammer.js
/* Hammer's high-level events example */
var element = document.getElementById('test_el');
var hammertime = Hammer(element...
jQuery Mobile? Sencha Touch?
check for support of IE10+
and “this is a touch device”
assumptions
debugging/testing
Chrome DevTools / Using the Console / Monitoring events
chrome://flags/#touch-events
beware inaccurate emulation
Issue 181204: [...] event order different from real devices
Fixed in Chrome (Canary) 37
Bug 920956 - DevTools touch emulation: suppress regular mouse events ...
beware inaccurate
implementation
Bug 861876 - [...] multiple mousemoves being fired
Bug 861876 - [...] preventDefault on touchstart doesn't stop synthetic mouse events
further reading...
•  Matt Gaunt – Touch Feedback for Mobile Sites
•  Jonathan Stark – FastActive
•  Stephen Woods – HTML5 Touch Interfaces
•...
•  Rick Byers + Boris Smus (Google I/O) – Point, Click, Tap, Touch -
Building Multi-Device Web Interfaces
•  Grant Goodale...
•  Tim Kadlec – Avoiding the 300ms Click Delay, Accessibly
•  Microsoft – Pointer events updates (differences between IE10...
•  Stu Cox – The Good & Bad of Level 4 Media Queries
•  Peter-Paul Koch – Touch table
•  Peter-Paul Koch – Preventing the ...
youtube.com/watch?v=AZKpByV5764
get in touch
@patrick_h_lauke
github.com/patrickhlauke/touch
slideshare.net/redux
paciellogroup.com
splintered.co.uk
Getting touchy - an introduction to touch and pointer events / Web Rebels / Oslo / 22 May 2014
Getting touchy - an introduction to touch and pointer events / Web Rebels / Oslo / 22 May 2014
Getting touchy - an introduction to touch and pointer events / Web Rebels / Oslo / 22 May 2014
Getting touchy - an introduction to touch and pointer events / Web Rebels / Oslo / 22 May 2014
Getting touchy - an introduction to touch and pointer events / Web Rebels / Oslo / 22 May 2014
Getting touchy - an introduction to touch and pointer events / Web Rebels / Oslo / 22 May 2014
Getting touchy - an introduction to touch and pointer events / Web Rebels / Oslo / 22 May 2014
Getting touchy - an introduction to touch and pointer events / Web Rebels / Oslo / 22 May 2014
Getting touchy - an introduction to touch and pointer events / Web Rebels / Oslo / 22 May 2014
Upcoming SlideShare
Loading in …5
×

Getting touchy - an introduction to touch and pointer events / Web Rebels / Oslo / 22 May 2014

2,398 views

Published on

Published in: Technology
  • Be the first to comment

Getting touchy - an introduction to touch and pointer events / Web Rebels / Oslo / 22 May 2014

  1. 1. gettingtouchy AN INTRODUCTION TO TOUCH AND POINTER EVENTS Patrick H. Lauke / Web Rebels / Oslo / 22 May 2014
  2. 2. patrickhlauke.github.io/touch
  3. 3. Touch/pointer events test results
  4. 4. “how can I make my website work on touch devices?”
  5. 5. you don't need touch events browsers emulate regular mouse events
  6. 6. patrickhlauke.github.io/touch/tests/event-listener_mouse-only.html
  7. 7. patrickhlauke.github.io/touch/tests/event-listener_mouse-only.html
  8. 8. compatibility mouse events (mouseenter) > mouseover > mousemove* > mousedown > (focus) > mouseup > click * only a single “sacrificial” mousemove event fired
  9. 9. on first tap (mouseenter) > mouseover > mousemove > mousedown > (focus) > mouseup > click subsequent taps mousemove > mousedown > mouseup > click tapping away mouseout > (blur) focus / blur only on focusable elements in Firefox mouseout not on iOS Safari/WebView (e.g. iOS Chrome) Opera Mobile and
  10. 10. emulation works, but is limiting/problematic
  11. 11. 1.  delayed event dispatch 2.  mousemove doesn't track
  12. 12. 1.  delayed event dispatch 2.  mousemove doesn't track
  13. 13. patrickhlauke.github.io/touch/tests/event-listener_show-delay.html
  14. 14. patrickhlauke.github.io/touch/tests/event-listener_show-delay.html
  15. 15. 1.  delayed event dispatch 2.  mousemove doesn't track
  16. 16. patrickhlauke.github.io/touch/particle/2
  17. 17. patrickhlauke.github.io/touch/particle/2 (iOS7 bug: moving finger fires mousemove on scroll)
  18. 18. “we need to go deeper...”
  19. 19. touch events introduced by Apple, adopted in Chrome/Firefox/Opera www.w3.org/TR/touch-events
  20. 20. touchstart touchmove touchend touchcancel touchenter touchleave
  21. 21. patrickhlauke.github.io/touch/tests/event-listener_all-no-timings.html
  22. 22. patrickhlauke.github.io/touch/tests/event-listener_all-no-timings.html Bug 128534 - 'mouseenter' mouse compat event not fired...
  23. 23. events fired on tap touchstart > [touchmove]+ > touchend > (mouseenter) > mouseover > mousemove > mousedown > (focus) > mouseup > click (mouse events only fired for single-finger tap)
  24. 24. on first tap touchstart > [touchmove]+ > touchend > (mouseenter) > mouseover > mousemove > mousedown > (focus) > mouseup > click subsequent taps touchstart > [touchmove]+ > touchend > mousemove > mousedown > mouseup > click tapping away mouseout > (mouseleave) > (blur)
  25. 25. •  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 the touchmove some browsers outright weird...
  26. 26. Browser/Android 4.3 (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
  27. 27. Touch/pointer events test results
  28. 28. touch events vs limitations/problems
  29. 29. 1.  delayed event dispatch 2.  mousemove doesn't track
  30. 30. 1.  delayed event dispatch 2.  mousemove doesn't track
  31. 31. patrickhlauke.github.io/touch/tests/event-listener_show-delay.html
  32. 32. why the delay? double-tap to zoom (mostly anyway)
  33. 33. what if browsers didn't wait?
  34. 34. Puffin/Android double-tap zooms and fires mouse events + click (also, doesn't support touch events)
  35. 35. Try it out in Chrome? chrome://flags/
  36. 36. when does the delay happen?
  37. 37. patrickhlauke.github.io/touch/tests/event-listener.html
  38. 38. touch / mouse events delay touchstart > [touchmove]+ > touchend > [300ms delay] (mouseenter) > mouseover > mousemove > mousedown > (focus) > mouseup > click
  39. 39. “how can we make it feel responsive like a native app?”
  40. 40. react to events fired before the 300ms delay...
  41. 41. touchstart for an “immediate” control (fire/jump button on a game)
  42. 42. touchend for a control that fires after finger lifted
  43. 43. interlude: simple feature detection for touch events
  44. 44. /* 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 */
  45. 45. /* common performance “trick” */ var clickEvent = ( 'ontouchstart' in window ? 'touchend' : 'click' ); blah.addEventListener( clickEvent , function() { ... }, false);
  46. 46. don't make it touch-exclusive
  47. 47. /* common performance “trick” */ var clickEvent = ( 'ontouchstart' in window ? 'touchend' : 'click'); ... /* if touch events are supported, only listen to touchend, not click */
  48. 48. hybrid devices touch + mouse + keyboard
  49. 49. Android + mouse – behaves like touch touchstart > touchend > mouseover > mousemove > mousedown > (focus) > mouseup > click
  50. 50. Blackberry PlayBook 2.0 + mouse - like desktop mouse mouseover > mousedown > mousemove > mouseup > click
  51. 51. Android + keyboard – like desktop keyboard focus > click
  52. 52. iOS + VoiceOver (with/without keyboard) – similar to touch focus > touchstart > touchend > (mouseenter) > mouseover > mousemove > mousedown > blur > mouseup > click
  53. 53. Android + TalkBack – keyboard/mouse hybrid focus > blur > mousedown > mouseup > click > focus(?)
  54. 54. hacks.mozilla.org - Detecting touch [...]
  55. 55. /* 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 ... */ }
  56. 56. touch or mouse or keyboard
  57. 57. touch and mouse and keyboard
  58. 58. /* doubled-up event listeners */ foo.addEventListener(' touchend ', someFunction, false); foo.addEventListener(' click ', someFunction, false);
  59. 59. /* prevent delay + mouse events */ foo.addEventListener(' touchstart ', function(e) { e.preventDefault(); }, false); /* doubled-up event listeners */ foo.addEventListener('touchend', someFunction, false); foo.addEventListener('click', someFunction, false);
  60. 60. preventDefault() kills scrolling, pinch/zoom, etc
  61. 61. apply preventDefault() carefully (just on buttons/links, not entire page)
  62. 62. github.com/ftlabs/fastclick
  63. 63. browsers working to remove double-tap to zoom delay (when page not zoomable)
  64. 64. <meta name="viewport" content="user-scalable=no"> patrickhlauke.github.io/touch/tests/event-listener_user-scalable-no.html
  65. 65. <meta name="viewport" content="user-scalable=no"> patrickhlauke.github.io/touch/tests/event-listener_user-scalable-no.html
  66. 66. ... content="minimum-scale=1, maximum-scale=1" patrickhlauke.github.io/touch/tests/event-listener_minimum-maximum-scale.html
  67. 67. ... content="minimum-scale=1, maximum-scale=1" patrickhlauke.github.io/touch/tests/event-listener_minimum-maximum-scale.html
  68. 68. Bug 922896 - Optimizations to remove 300ms [...] delay [RESOLVED - FIXED]
  69. 69. what about accessibility?
  70. 70. patrickhlauke.github.io/touch/tests/event-listener_user-scalable-no.html
  71. 71. Chrome 32+ / Android: ... content="width=device-width" updates.html5rocks.com/2013/12/300ms-tap-delay-gone-away
  72. 72. Bug 941995 - Remove 300ms [...] on "responsive" pages
  73. 73. patrickhlauke.github.io/touch/tests/event-listener_user-scalable-no.html
  74. 74. iOS/Safari designed themselves into a corner: “double-tap to scroll” bugs.webkit.org/show_bug.cgi?id=122212
  75. 75. 1.  delayed event dispatch 2.  mousemove doesn't track
  76. 76. patrickhlauke.github.io/touch/particle/2
  77. 77. patrickhlauke.github.io/touch/particle/2 (iOS7 bug: moving finger fires mousemove on scroll)
  78. 78. events fired on tap touchstart > [touchmove]+ > touchend > (mouseenter) > mouseover > mousemove* > mousedown > (focus) > mouseup > click * mouse event emulation fires only a single mousemove too many touchmove events prevent mouse compatibility events after touchend
  79. 79. doubling up handling of mousemove and touchmove
  80. 80. var posX, posY; ... function positionHandler(e) { posX = e.clientX ; posY = e.clientY ; } ... canvas.addEventListener(' mousemove ', positionHandler, false);
  81. 81. var posX, posY; ... function positionHandler(e) { /* handle both mouse and touch */ } ... canvas.addEventListener(' mousemove ', positionHandler, false); canvas.addEventListener(' touchmove ', positionHandler, false);
  82. 82. 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
  83. 83. partial interface MouseEvent { readonly attribute double screenX; readonly attribute double screenY; readonly attribute double pageX ; readonly attribute double pageY ; readonly attribute double clientX; readonly attribute double clientY; readonly attribute double x ; readonly attribute double y ; readonly attribute double offsetX ; readonly attribute double offsetY ; }; www.w3.org/TR/cssom-view/#extensions-to-the-mouseevent-interface
  84. 84. 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
  85. 85. 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
  86. 86. touches all touch points on screen targetTouches all touch points that started on the element changedTouches touch points that caused the event to fire
  87. 87. patrickhlauke.github.io/touch/touchlist-objects
  88. 88. 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 );
  89. 89. patrickhlauke.github.io/touch/particle/3
  90. 90. tracking finger movement over time ... swipe gestures
  91. 91. patrickhlauke.github.io/touch/swipe
  92. 92. patrickhlauke.github.io/touch/picture-slider
  93. 93. don't forget mouse/keyboard!
  94. 94. bradfrostweb.com/demo/mobile-first
  95. 95. touchmove fires...a lot!
  96. 96. do absolute minimum on each touchmove (usually: store coordinates)
  97. 97. heavy JavaScript on setInterval or requestAnimationFrame
  98. 98. patrickhlauke.github.io/touch/touch-limit
  99. 99. why stop at a single point? multitouch support
  100. 100. 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
  101. 101. /* iterate over touch array */ for (i=0; i< e.targetTouches .length; i++) { ... posX = e.targetTouches[i].clientX ; posY = e.targetTouches[i].clientY ; ... }
  102. 102. patrickhlauke.github.io/touch/tracker/multi-touch-tracker.html
  103. 103. iOS/iPad preventDefault() can't override 4-finger gestures
  104. 104. iOS7/Safari preventDefault() can't override back/forward swipe gestures
  105. 105. multitouch gestures
  106. 106. /* 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 */ } /* not supported in Chrome/Firefox/Opera */
  107. 107. /* with some trigonometry we can replicate these from basic principles. */ var distance = Math.sqrt(Math.pow(...)+Math.pow(...)); var angle = Math.atan2(...);
  108. 108. patrickhlauke.github.io/touch/picture-organiser
  109. 109. not all old/cheap devices/OSs support multitouch!
  110. 110. HTC Hero – Android 2.1
  111. 111. LG Optimus 2X – Android 2.3.7
  112. 112. ZTE Open – Firefox OS 1.1
  113. 113. what about Internet Explorer?
  114. 114. up to IE9 (Win7 / WinPhone7.5) only mouse events
  115. 115. in IE10 Microsoft introduced Pointer Events
  116. 116. David Rousset - Unifying touch and mouse [...]
  117. 117. not just some “not invented here” technology
  118. 118. Pointer Events - W3C Candidate Recommendation 09 May 2013
  119. 119. Pointer Events - W3C Editor's Draft 14 May 2014
  120. 120. html5labs.interoperabilitybridges.com/prototypes/...
  121. 121. Issue 162757: Implement pointer events in Chrome behind experimental flag
  122. 122. Bug 822898 - Implement pointer events
  123. 123. ...what about Apple?
  124. 124. Bug 105463 - Implement pointer events RESOLVED WONTFIX
  125. 125. patrickhlauke.github.io/touch/tests/event-listener_all-no-timings.html
  126. 126. patrickhlauke.github.io/touch/tests/event-listener_all-no-timings.html
  127. 127. events fired on tap mousemove* > pointerover > mouseover > pointerenter > mouseenter > pointerdown > mousedown > pointermove > mousemove > gotpointercapture > focus > 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)
  128. 128. vendor-prefixed in IE10 MSPointerDown etc navigator.msMaxTouchPoints -ms-touch-action unprefixed in IE11 (but prefixed versions still mapped for compatibility)
  129. 129. /* 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; } /* plus all the classic MouseEvent attributes like clientX , clientY , etc */
  130. 130. simple feature detection for pointer events
  131. 131. /* detecting pointer events support */ if ( window.PointerEvent ) { /* some clever stuff here but this covers touch, stylus, mouse, etc */ } /* still listen to click for keyboard! */
  132. 132. /* detect maximum number of touch points */ if ( navigator.maxTouchPoints > 0 ) { /* device with a touchscreen */ } if ( navigator.maxTouchPoints > 1 ) { /* multitouch-capable device */ }
  133. 133. are pointer events better?
  134. 134. no need for separate mouse or touch event listeners
  135. 135. /* touch events: separate handling */ foo.addEventListener('touchmove', ... , false); foo.addEventListener('mousemove', ... , false); /* pointer events: single listener for mouse, stylus, touch */ foo.addEventListener(' pointermove ', ... , false);
  136. 136. no need for separate mouse or touch code to get x / y coords
  137. 137. /* Pointer Events extend Mouse Events */ foo.addEventListener(' pointermove ', function(e) { ... posX = e.clientX ; posY = e.clientY ; ... }, false); www.w3.org/TR/pointerevents/#pointerevent-interface
  138. 138. but you can distinguish mouse or touch or stylus if needed
  139. 139. foo.addEventListener('pointermove', function(e) { ... switch( e.pointerType ) { case ' mouse ': ... break; case ' pen ': ... break; case ' touch ': ... break; default : /* future-proof */ } ... } , false);
  140. 140. pointer events vs limitations/problems of mouse event emulation
  141. 141. 1.  delayed event dispatch 2.  mousemove doesn't track
  142. 142. 1.  delayed event dispatch 2.  mousemove doesn't track
  143. 143. patrickhlauke.github.io/touch/tests/event-listener_show-delay.html (IE/Win8 has double-tap to zoom, so problem on desktop too)
  144. 144. patrickhlauke.github.io/touch/tests/event-listener.html
  145. 145. patrickhlauke.github.io/touch/tests/event-listener.html
  146. 146. pointer / mouse events and delay mousemove > pointerover > mouseover > pointerenter > mouseenter > pointerdown > mousedown > pointermove > mousemove > gotpointercapture > focus > pointerup > mouseup > lostpointercapture > pointerout > mouseout > pointerleave > mouseleave > [300ms delay] click
  147. 147. “how can we make it feel responsive like a native app?”
  148. 148. we could try a similar approach to touch events...
  149. 149. •  double-up listeners - pointerup and click •  prevent code firing twice - preventDefault preventDefault() on pointerdown stops mouse compatibility events, but click is not considered mouse compatibility event
  150. 150. patrickhlauke.github.io/touch/tests/event-listener.html
  151. 151. touch-action
  152. 152. CSS property touch-action: auto | none | [ pan-x || pan-y ] | manipulation 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
  153. 153. touch-action:none kills scrolling, long-press, pinch/zoom
  154. 154. touch-action:manipulation
  155. 155. patrickhlauke.github.io/touch/tests/event-listener_touch[...]
  156. 156. Bug 979345 - Implement touch-action:manipulation [...]
  157. 157. Issue 349016: Add support for touch-action:manipulation
  158. 158. Bug 133114 - Implement " touch-action:manipulation " [...]
  159. 159. 1.  delayed event dispatch 2.  mousemove doesn't track
  160. 160. patrickhlauke.github.io/touch/particle/2
  161. 161. touch-action:none
  162. 162. patrickhlauke.github.io/touch/particle/2a
  163. 163. what about multitouch?
  164. 164. /* 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 ': /* remove the relevant array entry */ break; }
  165. 165. patrickhlauke.github.io/touch/tracker/multi-touch-tracker- pointer.html (note multiple isPrimary pointers)
  166. 166. /* 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... */
  167. 167. /* advanced topic: pointer capture */ gotpointercapture / lostpointercapture element.setPointerCapture(pointerId) patrickhlauke.github.io/touch/tests/pointercapture.html
  168. 168. what about backwards- compatibility?
  169. 169. touchstart > [touchmove]+ > touchend > [300ms delay] > mouseover > mousemove > mousedown > mouseup > click vs pointerover > mouseover > pointerdown > mousedown > pointermove > mousemove > pointerup > mouseup > pointerout > mouseout > [300ms delay] > click
  170. 170. W3C Touch Events Community Group
  171. 171. /* cover all cases (hat-tip Stu Cox) */ if ('onpointerdown' in window) { /* bind to Pointer Events: pointerdown, pointerup, etc */ } else { /* bind to mouse events: mousedown, mouseup, etc */ if ('ontouchstart' in window) { /* bind to Touch Events: touchstart, touchend, etc */ } } /* bind to keyboard / click */
  172. 172. polyfills for pointer events (code for tomorrow, today)
  173. 173. HandJS
  174. 174. www.catuhe.com/msdn/handjs/
  175. 175. Polymer
  176. 176. GitHub - Polymer/PointerEvents
  177. 177. /* Polymer's PointerEvents are not fired unless an element has a (custom) touch-action attribute */ <div id="foo" touch-action="none" ></div>
  178. 178. utility libraries (because life is too short to hand-code gesture support)
  179. 179. Hammer.js
  180. 180. /* Hammer's high-level events example */ var element = document.getElementById('test_el'); var hammertime = Hammer(element).on("swipeleft swiperight", function(event) { /* handle horizontal swipes */ });
  181. 181. jQuery Mobile? Sencha Touch? check for support of IE10+ and “this is a touch device” assumptions
  182. 182. debugging/testing
  183. 183. Chrome DevTools / Using the Console / Monitoring events
  184. 184. chrome://flags/#touch-events
  185. 185. beware inaccurate emulation
  186. 186. Issue 181204: [...] event order different from real devices Fixed in Chrome (Canary) 37
  187. 187. Bug 920956 - DevTools touch emulation: suppress regular mouse events ...
  188. 188. beware inaccurate implementation
  189. 189. Bug 861876 - [...] multiple mousemoves being fired
  190. 190. Bug 861876 - [...] preventDefault on touchstart doesn't stop synthetic mouse events
  191. 191. further reading...
  192. 192. •  Matt Gaunt – Touch Feedback for Mobile Sites •  Jonathan Stark – FastActive •  Stephen Woods – 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
  193. 193. •  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
  194. 194. •  Tim Kadlec – Avoiding the 300ms Click Delay, Accessibly •  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 – Make your site work on touch devices •  Stu Cox – You can't detect a touchscreen •  Tilo Mitra – The State of Gestures •  Microsoft – Hover touch support (IE10/IE11) •  W3C Media Queries Level 4 – pointer
  195. 195. •  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 •  Edge Conference (Feb 2013 London) – Panel: Input •  Edge Conference (Mar 2014 London) – Panel: Pointers and Interactions •  Trent Walton – Device-Agnostic •  Stu Cox – The Golden Pattern for Handling Touch Input •  Matt Gaunt – ‘Focusing’ on the Web Today •  Mobiscroll – Working with touch events
  196. 196. youtube.com/watch?v=AZKpByV5764
  197. 197. get in touch @patrick_h_lauke github.com/patrickhlauke/touch slideshare.net/redux paciellogroup.com splintered.co.uk

×