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,248 views

Published on

Published in: Technology
0 Comments
8 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
2,248
On SlideShare
0
From Embeds
0
Number of Embeds
183
Actions
Shares
0
Downloads
14
Comments
0
Likes
8
Embeds 0
No embeds

No notes for slide

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

×