Touch events
By Flavio Copes
Learn the basics of touch events in JavaScript, handling touchstart, touchend, touchmove, and touchcancel to track taps and multitouch on mobile devices.
See more on JavaScript events
Touch events are the events triggered when viewing a page on a touch device, like a smartphone or a tablet. They let you react to fingers touching the screen, moving across it, and lifting off, including multiple fingers at once.
We have 4 touch events:
touchstarta touch event has started (the surface is touched)touchenda touch event has ended (the surface is no longer touched)touchmovethe finger (or whatever is touching the device) moves over the surfacetouchcancelthe touch event has been cancelled
You listen for them like any other event:
const link = document.getElementById('my-link')
link.addEventListener('touchstart', (event) => {
// touch event started
})
What’s inside the event
Every time one of those events fires we are passed a touch event object.
Since more than one finger can touch the screen at the same time, the event doesn’t carry a single position. It carries lists of touch points:
touchesevery finger currently on the screentargetTouchesthe fingers currently on the element that fired the eventchangedTouchesthe fingers involved in this specific event (fortouchend, the ones that just lifted)
Each item in those lists is a Touch object, with these properties:
identifieran unique identifier for this specific touch point. Used to track multi-touch events. Same finger = same identifier.clientX/clientYthe x and y coordinates relative to the browser window, regardless of scrollingscreenX/screenYthe x and y coordinates in the screen coordinatespageX/pageYthe x and y coordinates in the page coordinates (including scrolling)targetthe element touched
So to track a single finger while it moves, you read the first item of changedTouches:
const area = document.getElementById('drawing-area')
area.addEventListener('touchmove', (event) => {
const touch = event.changedTouches[0]
console.log(touch.clientX, touch.clientY)
})
Moving one finger across the element logs a stream of coordinate pairs, one per event.
Watch out for scrolling
A common surprise: you call event.preventDefault() inside a touchmove handler to stop the page from scrolling, and nothing happens. The browser also prints a warning in the console.
That’s because browsers treat touchstart and touchmove listeners added on window, document, or body as passive by default, to keep scrolling smooth. A passive listener is not allowed to cancel the event.
The fix is to declare the listener as non-passive:
area.addEventListener('touchmove', (event) => {
event.preventDefault()
}, { passive: false })
Only do this on the specific element that needs it, since it forces the browser to wait for your handler before scrolling.
Related posts about platform: