Touch Gestures
Traditionally, Web relies on a mouse and a keyboard as the only input devices, while mobile devices are mostly controlled by touch. Mobile Web started with a bit touchy solution of translating touch events to mouse events like mousedown
.
Newer HTML5 approach is to embrace touch as the first-class input mean, allowing Web applications to intercept and identify complex multitouch gestures, free-hand drawing etc. Unfortunately, the support is twofold - either via touch events like touchstart
that were first introduced by Apple and standardized later as a de facto solution, when other vendors went the same route, or via the newer, more general Pointer Events specification, initiated by Microsoft.
API glimpse
Touch Events API
element.addEventListener('touchstart', listener)
- An event triggered when the finger has been placed on a DOM element.
element.addEventListener('touchmove', listener)
- An event triggered when the finger has been dragged along a DOM element.
element.addEventListener('touchend', listener)
- An event triggered when the finger has been removed from a DOM element.
Pointer Events API
element.addEventListener('pointerdown', listener)
- An event triggered when the finger has been placed on a DOM element.
element.addEventListener('pointermove', listener)
- An event triggered when the finger has been dragged along a DOM element.
element.addEventListener('pointerup', listener)
- An event triggered when the finger has been removed from a DOM element.
Live Demo
-
function startDrag(e) { this.ontouchmove = this.onmspointermove = moveDrag; this.ontouchend = this.onmspointerup = function () { this.ontouchmove = this.onmspointermove = null; this.ontouchend = this.onmspointerup = null; } var pos = [this.offsetLeft, this.offsetTop]; var that = this; var origin = getCoors(e); function moveDrag(e) { var currentPos = getCoors(e); var deltaX = currentPos[0] - origin[0]; var deltaY = currentPos[1] - origin[1]; this.style.left = (pos[0] + deltaX) + 'px'; this.style.top = (pos[1] + deltaY) + 'px'; return false; // cancels scrolling } function getCoors(e) { var coors = []; if (e.targetTouches && e.targetTouches.length) { var thisTouch = e.targetTouches[0]; coors[0] = thisTouch.clientX; coors[1] = thisTouch.clientY; } else { coors[0] = e.clientX; coors[1] = e.clientY; } return coors; } } var elements = document.querySelectorAll('.test-element'); [].forEach.call(elements, function (element) { element.ontouchstart = element.onmspointerdown = startDrag; }); document.ongesturechange = function () { return false; }
-
<div class="test-element">Drag me with one finger</div> <div class="test-element">Drag me with another finger</div> <div class="test-element">Drag me too</div> <p><small>Based on demo from <a href="https://www.quirksmode.org/m/tests/drag2.html">QuirksMode.org</a>.</small></p>
-
.test-element { height: 100px; background-color: black; width: 100px; z-index: 5; position: absolute; top: 15px; left: 15px; color: white; text-align: center; -ms-touch-action: none; } .test-element:nth-child(2) { top: 150px; left: 150px; } .test-element:nth-child(3) { top: 50px; left: 100px; }