Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Getting touchy - an introduction to touch and p...

Getting touchy - an introduction to touch and pointer events / JavaScript Days 2016

Slides from my 1 day workshop at HTML5 Days / JavaScript Days in Munich, Germany, 22 March 2016

Beyond smartphones and tablets, touchscreens are finding their way into laptops and even desktop computers. With hardware support for touch becoming increasingly ubiquitous, it's time to explore what new possibilities are available to developers. This session will cover the basics of handling touch events - from making sure simple single-tap interactions are as responsive as possible, all the way to examples of full multitouch, gesture-enabled elements.

Evergreen slidedeck at https://patrickhlauke.github.io/getting-touchy-presentation/ / https://github.com/patrickhlauke/getting-touchy-presentation

Patrick H. Lauke

March 22, 2016
Tweet

More Decks by Patrick H. Lauke

Other Decks in Technology

Transcript

  1. getting touchy AN INTRODUCTION TO TOUCH AND POINTER EVENTS Patrick

    H. Lauke / Last major changes: 18 March 2016
  2. about me... •  senior accessibility consultant at The Paciello Group

    •  previously developer relations at Opera •  member of W3C Touch Events Community Group •  chair (since March 2016) of W3C Pointer Events Working Group
  3. compatibility mouse events (mouseenter) > mouseover > mousemove* > mousedown

    > (focus) > mouseup > click * only a single “sacrificial” mousemove event fired
  4. 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; subtle differences between browsers Mobile/tablet touchscreen activation/tap event order
  5. touch events introduced by Apple, adopted in Chrome/Firefox/Opera (and belatedly

    IE/Edge – more on that later) www.w3.org/TR/touch-events
  6. events fired on tap touchstart > [touchmove]+ > touchend >

    (mouseenter) > mouseover > mousemove > mousedown > (focus) > mouseup > click (mouse events only fired for single-finger tap)
  7. 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)
  8. •  too many touchmove events prevent mouse compatibility events after

    touchend (not considered a "clean" tap) •  too many touchmove events on activatable elements can lead to touchcancel (in old Chrome/Browser versions) •  not all browsers consistently send touchmove •  differences in focus / blur and some mouse compatibility events (e.g. mouseenter / mouseleave ) •  some events may only fire when tapping away to another focusable element (e.g. blur ) some browsers outright weird...
  9. Browser/Android 4.3 mouseover > mousemove > touchstart > touchend >

    mousedown > mouseup > click Browser/Blackberry PlayBook 2.0 touchstart > mouseover > mousemove > mousedown > touchend > mouseup > click UC Browser 10.8/Android 6 mouseover > mousemove > touchstart > (touchmove)+ > touchend > mousedown > focus > mouseup > click
  10. touch / mouse events delay touchstart > [touchmove]+ > touchend

    > [300ms delay] (mouseenter) > mouseover > mousemove > mousedown > (focus) > mouseup > click
  11. touchend for a control that fires after finger lifted (but

    this can result in events firing after zoom/scroll)
  12. /* 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 */
  13. /* common performance “trick” */ var clickEvent = ( 'ontouchstart'

    in window ? 'touchend' : 'click' ); blah.addEventListener( clickEvent , function() { ... }, false);
  14. /* common performance “trick” */ var clickEvent = ( 'ontouchstart'

    in window ? 'touchend' : 'click'); ... /* if touch events are supported, only listen to touchend, not click */
  15. Android + mouse – behaves like touch touchstart > touchend

    > mouseover > mousemove > mousedown > (focus) > mouseup > click
  16. Blackberry PlayBook 2.0 + mouse - like desktop mouseover >

    mousedown > (mousemove)+ > mouseup > click
  17. Blackberry Leap (BBOS 10.1) + mouse - like desktop mouseover

    > mousedown > (mousemove)+ > mouseup > click
  18. Windows 10 Mobile/Microsoft Edge + mouse - like desktop mouseover

    > mousedown > (mousemove)+ > mouseup > click
  19. iOS + keyboard – similar to touch (TAB / ENTER)

    focus / touchstart > touchend > (mouseenter) > mouseover > mousemove > mousedown > blur > mouseup > click
  20. iOS + VoiceOver (with/without keyboard) – similar to touch focus

    / touchstart > touchend > (mouseenter) > mouseover > mousemove > mousedown > blur > mouseup > click
  21. Android 6.1/Chrome + TalkBack – simulates touch touchstart > touchend

    > mouseover > mouseenter > mousemove > mousedown > focus > mouseup > click
  22. Android 6.1/Firefox + TalkBack – similar to touch touchstart >

    mousedown > focus > touchend > mouseup > click
  23. further scenarios? •  desktop with external touchscreen •  desktop with

    external touchpad •  touchscreen laptop with non-touch second screen •  touchscreen laptop with trackpad/mouse •  ...and other permutations?
  24. /* 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 ... */ }
  25. /* doubled-up event listeners */ foo.addEventListener(' touchend ', someFunction, false);

    foo.addEventListener(' click ', someFunction, false); /* but this would fire our function twice for touch? */ patrickhlauke.github.io/touch/tests/event-listener_naive-event-doubling.html
  26. /* doubled-up event listeners */ foo.addEventListener('touchend', function(e) { /* prevent

    mouse events + click */ e.preventDefault(); /* then trigger the function */ someFunction(e); }, false); foo.addEventListener('click', someFunction, false); patrickhlauke.github.io/touch/tests/event-listener_naive-event-doubling-fixed.html
  27. /* doubled-up event listeners */ foo.addEventListener('touchend', someFunction, false); foo.addEventListener('click', someFunction,

    false); /* prevent mouse events + click as part of the common handler */ function someFunction(e) { ... if (e.type == 'touchend') { e.preventDefault(); } ... }
  28. iOS/Safari designed themselves into a corner: “double-tap to scroll” Bug

    122212 - Optimizations to remove 300ms touch > mouse events delay
  29. Changeset 191072 - Web pages with unscalable viewports shouldn't have

    a single tap delay (change coming to iOS 9.3 – currently in beta)
  30. Bug 151077 - Fast-clicking should trigger when scale is equal

    to explicitly set initial scale (change coming to iOS 9.3 – currently in beta)
  31. no concept of hover on touch devices iOS fakes it,

    Samsung Galaxy Note II/Pro + stylus, ...
  32. iOS "fakes" hover support: stops event sequence on content change

    iOS Developer Library - Safari Web Content Guide - Handling Events
  33. YouTube: Samsung Galaxy Note Pro 12.2 stylus hover ...but you

    can't rely on this, as most devices don't have it...
  34. /* MQ4 Interaction Media Features*/ pointer: none | coarse |

    fine hover: none | on-demand | hover any-pointer: none | coarse | fine any-hover: none | on-demand | hover
  35. /* Naive uses of Interaction Media Features */ @media (hover:

    hover) { /* primary input has hover...so we can rely on it? */ } @media (pointer: fine) { /* primary input has fine pointer precision... so make all buttons/controls small? */ } /* hover and pointer only check "primary" input, but what if there's a secondary input that lacks capabilities? */
  36. /* Better uses of Interaction Media Features */ @media (any-hover:

    none) { /* at least one input lacks hover capability... don't rely on it or avoid altogether */ } @media (any-pointer: coarse) { /* at least one input has coarse pointer precision... provide larger buttons/controls for touch */ } /* test for presence of *any* "least capable" input (primary or not) */
  37. 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
  38. var posX, posY; ... function positionHandler(e) { posX = e.clientX

    ; posY = e.clientY ; } ... canvas.addEventListener(' mousemove ', positionHandler, false);
  39. var posX, posY; ... function positionHandler(e) { posX = e.clientX

    ; posY = e.clientY ; } ... canvas.addEventListener(' mousemove ', positionHandler, false); canvas.addEventListener(' touchmove ', positionHandler, false); /* but this won't work for touch... */
  40. 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; // [DOM4] UI Events readonly attribute unsigned short buttons; }; www.w3.org/TR/DOM-Level-2-Events/events.html#Events-MouseEvent www.w3.org/TR/uievents/#events-mouseevents
  41. 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
  42. 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
  43. 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
  44. TouchList differences touches all touch points on screen targetTouches all

    touch points that started on the element changedTouches touch points that caused the event to fire
  45. changedTouches depending on event: •  for touchstart , all new

    touch points that became active •  for touchmove , all touch points that changed/moved since last event •  for touchend / touchcancel , touch points that were removed (and are not active anymore at this point)
  46. 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 );
  47. TouchList collections order •  order of individual Touch objects in

    a TouchList can change •  e.g. targetTouches[0] not guaranteed to always be the same finger when dealing with multitouch •  not problematic for single-finger interactions, but use identifier property for each Touch to explicitly track a particular touch point / finger in multitouch
  48. Function.prototype.debounce = function (milliseconds, context) { var baseFunction = this,

    timer = null, wait = milliseconds; return function () { var self = context || this, args = arguments; function complete() { baseFunction.apply(self, args); timer = null; } if (timer) { clearTimeout(timer); } timer = setTimeout(complete, wait); }; }; window.addEventListener('touchmove', myFunction.debounce(250) );
  49. Function.prototype.throttle = function (milliseconds, context) { var baseFunction = this,

    lastEventTimestamp = null, limit = milliseconds; return function () { var self = context || this, args = arguments, now = Date.now(); if (!lastEventTimestamp || now - lastEventTimestamp >= limit) { lastEventTimestamp = now; baseFunction.apply(self, args); } }; }; window.addEventListener('touchmove', myFunction.throttle(250) );
  50. 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
  51. /* iterate over touch array */ for (i=0; i< e.targetTouches

    .length; i++) { ... posX = e.targetTouches[i].clientX ; posY = e.targetTouches[i].clientY ; ... }
  52. /* 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 */
  53. /* with some trigonometry we can replicate these from basic

    principles. */ var distance = Math.sqrt(Math.pow(...)+Math.pow(...)); var angle = Math.atan2(...);
  54. not defined in spec, but de facto yes in most

    modern browsers patrickhlauke.github.io/touch/gesture-touch
  55. e.g. older versions of Chrome fire touchcancel on scroll/zoom YouTube:

    Google Developers - Mobile Web Thursdays: Performance on Mobile
  56. Google Developers: A More Compatible, Smoother Touch (lots more complexity

    / edge cases, particularly for old browsers/devices)
  57. contrary to Apple's docs, onclick="" seems unnecessary (at least since

    iOS6, maybe earlier) patrickhlauke.github.io/touch/ios-clickable/
  58. mouse + click bubbling in iOS •  target element is

    a link or form control •  target or any ancestor (up to but not including body ) has explicit mouse or click handler (even if only empty function) •  target or any ancestor (up to and including document ) has cursor:pointer Quirksmode: Mouse event bubbling in iOS
  59. /* Extension to touch objects */ partial interface Touch {

    readonly attribute float radiusX; readonly attribute float radiusY; readonly attribute float rotationAngle; readonly attribute float force; };
  60. /* Touch Events – contact geometry */ partial interface Touch

    { readonly attribute float radiusX ; readonly attribute float radiusY ; readonly attribute float rotationAngle ; readonly attribute float force; };
  61. /* Touch Events – force */ partial interface Touch {

    readonly attribute float radiusX; readonly attribute float radiusY; readonly attribute float rotationAngle; readonly attribute float force ; }; force : value in range 0 – 1 . if no hardware support 0 (some devices, e.g. Nexus 10, "fake" force based on radiusX / radiusY )
  62. 3D Touch ≠ Force Touch •  Force Touch is Apple's

    proprietary extension to mouse events •  only aimed at force-enabled trackpads (new Apple models) •  new events: webkitmouseforcewillbegin , webkitmouseforcedown , webkitmouseforceup , webkitmouseforcechanged •  mouse events have additional webkitForce property Safari Developer Library: Responding to Force Touch Events
  63. interface Touch { readonly attribute long identifier; readonly attribute EventTarget

    target; readonly attribute long float screenX; readonly attribute long float screenY; readonly attribute long float clientX; readonly attribute long float clientY; readonly attribute long float pageX; readonly attribute long float pageY; };
  64. W3C Web Events WG - Touch Events errata (early effort

    to clarify grey areas, simplify language used)
  65. W3C Touch Events - Level 2 (Editor's Draft) (merges errata,

    touch events extensions, fractional touch coordinates)
  66. ...and some new inputs (though currently mapped to mouse) Building

    Xbox One Apps using HTML and JavaScript YouTube: Xbox One Edge Browser sends Pointer Events
  67. events fired on tap (IE10/IE11) mousemove* > pointerover > mouseover

    > pointerenter > mouseenter > pointerdown > mousedown > gotpointercapture > focus > pointermove > mousemove > pointerup > mouseup > lostpointercapture > pointerout > mouseout > pointerleave > mouseleave > click mouse events fired “inline” with pointer events (for a primary pointer, e.g. first finger on screen)
  68. current IE10/11 quirk ... pointerup > mouseup > lostpointercapture >

    pointerout > mouseout > pointerleave > mouseleave > click the fact that click comes last is a current IE10/11 quirk – according to spec it should come after pointerup > mouseup , and does already when using touch-action W3C Pointer Events WG mailing list - Jacob Rossi (Microsoft)
  69. events fired on tap (Edge) mousemove* > pointerover > mouseover

    > pointerenter > mouseenter > pointerdown > mousedown > focus gotpointercapture > pointermove > mousemove > pointerup > mouseup > lostpointercapture > click > pointerout > mouseout > pointerleave > mouseleave note click fired correctly after pointerup in Microsoft Edge
  70. /* 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 */
  71. /* detecting pointer events support */ if ( window.PointerEvent )

    { /* some clever stuff here but this covers touch, stylus, mouse, etc */ } /* still listen to click for keyboard! */
  72. /* detect maximum number of touch points */ if (

    navigator.maxTouchPoints > 0 ) { /* device with a touchscreen */ } if ( navigator.maxTouchPoints > 1 ) { /* multitouch-capable device */ }
  73. pointer / mouse events and delay ... [300ms delay] click

    ... 300ms delay just before click event
  74. •  double-up pointerup and click listeners? •  prevent code firing

    twice with preventDefault ? won't work: preventDefault() stops mouse compatibility events, but click is not considered mouse compatibility event
  75. CSS property what action should the browser handle? touch-action: auto

    | none | [ pan-x || pan-y ] | manipulation www.w3.org/TR/pointerevents/#the-touch-action-css-property only determines default touch action, does not stop compatibility mouse events nor click
  76. Pointer Events Level 2 (editor's draft) expanded set of values

    (useful for pull-to-refresh, carousels, etc) touch-action: auto | none | [ [ pan-x | pan-left | pan-right ] || [ pan-y | pan-up | pan-down ] ] | manipulation w3c.github.io/pointerevents/#the-touch-action-css-property
  77. /* touch events: separate handling */ foo.addEventListener('touchmove', ... , false);

    foo.addEventListener('mousemove', ... , false); /* pointer events: single listener for mouse, stylus, touch */ foo.addEventListener(' pointermove ', ... , false);
  78. /* Pointer Events extend Mouse Events */ foo.addEventListener(' pointermove ',

    function(e) { ... posX = e.clientX ; posY = e.clientY ; ... }, false); www.w3.org/TR/pointerevents/#pointerevent-interface
  79. foo.addEventListener('pointermove', function(e) { ... switch( e.pointerType ) { case '

    mouse ': ... break; case ' pen ': ... break; case ' touch ': ... break; default : /* future-proof */ } ... } , false);
  80. /* in IE11/Edge, pointerType returns a string in IE10, the

    return type is long */ MSPOINTER_TYPE_TOUCH: 0x00000002 MSPOINTER_TYPE_PEN: 0x00000003 MSPOINTER_TYPE_MOUSE: 0x00000004 MSDN: IE Dev Center - API reference - pointerType property
  81. /* PointerEvents don't have the handy TouchList objects, so we

    have to replicate something similar... */ var points = []; switch (e.type) { case ' pointerdown ': /* add to the array */ break; case ' pointermove ': /* update the relevant array entry's x and y */ break; case ' pointerup ': case ' pointercancel ': /* remove the relevant array entry */ break; }
  82. simultaneous use of inputs is hardware-dependent (e.g. Surface 3 "palm

    blocking" prevents concurrent touch/stylus/mouse, but not touch/external mouse/external stylus)
  83. /* like iOS/Safari, IE/Win has higher-level gestures , but these

    are not part of the W3C Pointer Events spec. Replicate these from basic principles again... */ MSDN IE10 Developer Guide: Gesture object and events
  84. /* Pointer Events - pressure */ 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; } pressure : value in range 0 – 1 . if no hardware support, 0.5 in active button state, 0 otherwise
  85. hovering stylus •  hardware-dependant •   pointermove fires •  

    pressure == 0 (non-active button state) •  track pointerdown / pointerup to be safe
  86. /* Pointer Events - contact geometry */ 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; } if hardware can't detect contact geometry, either 0 or "best guess" (e.g. for mouse/stylus, return width / height of 1 )
  87. /* Pointer Events - tilt */ 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; } tiltX / tiltY : value in degrees -90 – 90 . returns 0 if hardware does not support tilt
  88. pointermove fires if any property changes, not just x/y position

    ( width , height , tiltX , tiltY , pressure )
  89. •  touch events have implicit capture: once you start a

    touch movement on an element, events keep firing to the element even when moving outside the element's boundaries •  pointer events behave like mouse events: only fire events to an element while pointer (e.g. finger on touchscreen) inside element, but you can explicitly capture pointers
  90. /* events related to pointer capture */ gotpointercapture / lostpointercapture

    /* example of how to capture a pointer explicitly */ element.addEventListener('pointerdown', function(e) { this. setPointerCapture(e.pointerId) ; }, false } /* capture automatically released on pointerup / pointercancel or explicitly with releasePointerCapture() */ patrickhlauke.github.io/touch/tests/pointercapture.html
  91. 1.  performance issues (hit-testing) 2.  unified event model not "mobile

    first" 3.  difficult to implement "pull to refresh" 4.  we already have touch events
  92. 1.  performance issues (hit-testing) 2.  unified event model not "mobile

    first" 3.  difficult to implement "pull to refresh" 4.  we already have touch events 5.  Apple won't implement them...
  93. MSDN IEBlog: The Mobile Web should just work for everyone

    Windows Phone 8.1 Update now supports Pointer Events and Touch Events
  94. touchstart > [touchmove]+ > touchend > [300ms delay] > mouseover

    > mousemove > mousedown > mouseup > click vs pointerover > mouseover > pointerdown > mousedown > pointermove > mousemove > pointerup > mouseup > [300ms delay] > click > pointerout > mouseout > pointerleave > mouseleave
  95. events fired on tap (IE11) mousemove* > pointerover > mouseover

    > pointerenter > mouseenter > pointerdown > touchstart > mousedown > gotpointercapture > focus > pointermove > touchmove > mousemove > pointerup > touchend > mouseup > lostpointercapture > pointerout > mouseout > pointerleave > mouseleave > click IE11/Windows Phone 8.1u1 with "frankensteined" Pointer/Touch Events support (but not on desktop)
  96. events fired on tap (Edge 13) mousemove > pointerover >

    mouseover > pointerenter > mouseenter > pointerdown > touchstart > mousedown > focus gotpointercapture pointermove > mousemove > pointerup > touchend > mouseup > click > lostpointercapture > pointerout > mouseout > pointerleave > mouseleave essentially, relevant Touch Events after pointerdown and pointerup
  97. about:flags in Microsoft Edge to turn on touch events on

    desktop (e.g. touch-enabled laptops)
  98. /* 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 */
  99. events fired on tap with HandJS touchstart > pointerover >

    pointerenter > pointerdown > [touchmove > pointermove ]+ > touchend > pointerup > pointerout > pointerleave > [300ms delay] pointerenter > mouseenter > mousemove* > mousedown > mouseup > click (not correct order, but close enough?)
  100. /* adding jQuery PEP */ <script src="https://code.jquery.com/pep/0.4.1/pep.js"></script> /* need to

    use custom touch-action attribute, not CSS (yet) */ <button touch-action="none" >...</div>
  101. events fired on tap with PEP pointerover > pointerenter >

    pointerdown > touchstart > pointerup > pointerout > pointerleave > touchend > mouseover > mouseenter > mousemove > mousedown > mouseup > click essentially, relevant Pointer Events before touchstart and touchend
  102. ie­touch ­ useful or not? •  IE11/WinPhone8.1 and Edge/Win10Mobile now

    include touch events •  only needed for IE11/Edge on desktop/laptop with touch •  quick fix to enable existing/legacy touch events solutions(?)
  103. events fired on tap with ie­touch mousemove > pointerover >

    mouseover > pointerenter > mouseenter > pointerdown > touchstart > mousedown > gotpointercapture > focus > pointermove > touchmove mousemove > pointerup > touchend > mouseup > lostpointercapture > pointerout > mouseout > pointerleave > mouseleave > [300ms delay] click
  104. ie­touch peculiarities •   event object has no targetTouches TouchList

    •   touches acts as if it were targetTouches , so no touch points that didn't start on the element we're listening to are reported •   changedTouches seems to always contain same touch points as the touches TouchList
  105. /* Hammer's high-level events example */ var element = document.getElementById('test_el');

    var hammertime = new Hammer(element); hammertime.on("swipe", function(event) { /* handle horizontal swipes */ });
  106. enable touch events even without a touchscreen (to test "naive"

    'ontouchstart' in window code) chrome://flags/#touch-events
  107. no touch emulation, nor touch events + pointer events (like

    on real Windows 10 Mobile) emulation, in Edge/F12 Tools
  108. Input Device Capabilities •  currently limited usefulness - only has

    firesTouchEvents property •  limited use cases (see Identifying touch events that will trigger a tap / click, Identifying mouse events derived from touch events and Google Developer: Input Device Capabilities) •  easier to switch to Pointer Events (and add PEP)?
  109. myButton.addEventListener('touchstart', addHighlight, false); myButton.addEventListener('touchend', removeHighlight, false); myButton.addEventListener('mousedown', addHighlight, false); myButton.addEventListener('mouseup',

    removeHighlight, false); myButton.addEventListener('click', someFunction, false); /* addHighlight/removeHighlight will fire twice for touch (first for touch, then for mouse compatibility events); can't use e.preventDefault(), as we want to rely on 'click' */
  110. myButton.addEventListener('touchstart', addHighlight, false); myButton.addEventListener('touchend', removeHighlight, false); myButton.addEventListener('mousedown', function(e) { if

    (!e.sourceCapabilities.firesTouchEvents) { addHighlight(e); } } , false); myButton.addEventListener('mouseup', function(e) { if (!e.sourceCapabilities.firesTouchEvents) { removeHighlight(e); } } , false); myButton.addEventListener('click', someFunction, false); /* same function for touch and mouse, but if mouse check if source input fires touch events (i.e. this is a mouse compat event) */
  111. •  Matt Gaunt – Touch Feedback for Mobile Sites •

     Jonathan Stark – FastActive •  Stephen Woods – HTML5 Touch Interfaces •  YouTube: Stephen Woods – Responsive HTML5 Touch Interfaces •  Chris Wilson + Paul Kinlan – Touch And Mouse: Together Again For The First Time •  Ryan Fioravanti – Creating Fast Buttons for Mobile Web Applications •  Boris Smus – Multi-touch Web Development •  Boris Smus – Generalized input on the cross-device web •  Boris Smus – Interactive touch laptop experiments
  112. •  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
  113. •  Tim Kadlec – Avoiding the 300ms Click Delay, Accessibly

    •  David Rousset - Unifying touch and mouse [...] •  Microsoft – Pointer events updates (differences between IE10-IE11) •  Patrick H. Lauke – Webseiten zum Anfassen •  Patrick H. Lauke – Drei unter einem Dach: Pointer-Events für Maus, Stylus und Touchscreen •  Patrick H. Lauke – Erweiterte Interaktionsmöglichkeiten mit Touchscreens •  Patrick H. Lauke – Make your site work on touch devices •  Stu Cox – You can't detect a touchscreen
  114. •  Microsoft – Hover touch support (IE10/IE11) •  W3C Media

    Queries Level 4 – pointer •  Stu Cox – The Good & Bad of Level 4 Media Queries •  Peter-Paul Koch – Touch table •  Peter-Paul Koch – Preventing the touch default •  Peter-Paul Koch – Mouse event bubbling in iOS •  YouTube: Edge Conference (Feb 2013 London) – Panel: Input •  Edge Conference (Mar 2014 London) – Panel: Pointers and Interactions •  Trent Walton – Device-Agnostic
  115. •  Stu Cox – The Golden Pattern for Handling Touch

    Input •  Matt Gaunt – ‘Focusing’ on the Web Today •  Mobiscroll – Working with touch events •  Peter-Paul Koch – The iOS event cascade and innerHTML •  Patrick H. Lauke – Make your site work on touch devices •  Scott Jehl (Filament Group) – Tappy: A custom tap event handler •  Yehuda Katz – Touch events on the web are fundamentally unfinished
  116. •  Andrea Giammarchi – PointerEvents No More •  YouTube: Matt

    Gaunt (Google) - Touch in a Web App? No Problem •  Luke Wroblewski – How to Communicate Hidden Gestures •  David Washington - Designing custom touch interactions •  David Washington - Building pull-to-refresh •  Andy Peatling - JavaScript Pull to Refresh for the Web •  Tilo Mitra – The State of Gestures •  YouTube: Tilo Mitra (YUI) – The State of Gestures
  117. •  Rob Larsen - The Uncertain Web: Pointer Event Polyfill

    and Chrome Fragmentation •  Detlev Fisher - Implications of new input modes (touch, speech, gestures) for the Web Content Accessibility Guidelines •  Ralph Thomas - Towards declarative touch interactions •  Windows Dev Center: Windows desktop applications > Guidelines > Interaction (touch, keyboard, mouse, pen) •  Microsoft Open Technologies - jQuery Adopts Pointer Events
  118. •  jQuery blog - Getting on Point •  IEBlog -

    Pointer Events W3C Recommendation, Interoperable Touch, and Removing the Dreaded 300ms Tap Delay •  Microsoft Open Technologies - Pointer Events is now a W3C Standard •  Patrick H. Lauke (The Paciello Group) - Pointer Events advance to W3C Recommendation •  Jacob Rossi - The Input Shouldn't Matter •  hacks.mozilla.org - Pointer Events now in Firefox Nightly
  119. •  Rick Byers – Interoperability Case Studies at BlinkOn 5

    (touch-action) •  Mozilla Developer Network – Pointer Events •  Christian Saylor – A Touch of Brilliance: Why 3D Touch Matters •  Lukas Mathis – Usability on Mobile Is Getting Worse •  Rocket Insights – Initial thoughts on 3D Touch •  Wiser Coder – Disable “pull to refresh” in Chrome for Android
  120. •  Google Developers / Web Fundamentals: Add touch to your

    site •  Alex Gibson – Different ways to trigger touchcancel in mobile browsers •  BBC Global Experience Language: How to design for touch •  Google BlinkOn 5: Lightning talks / Mustaq Ahmed – Pointer Events in Chrome implementation update •  A Book Apart: Josh Clark – Designing for Touch