Touch Events & Pointer Events
Also Known As
touch events
pointer events
touchstart
pointerdown
passive listener
TL;DR
Handling touch input on mobile — the Pointer Events API unifies mouse, touch, and stylus into one event model, replacing the need for separate touch and mouse event handlers.
Explanation
Touch Events (legacy): touchstart, touchmove, touchend — each has a touches list of all active contact points. Pointer Events (modern): pointerdown, pointermove, pointerup, pointercancel — single event model for mouse (pointerId=1), touch (multiple pointers), and stylus. Use Pointer Events in new code. Touch performance: passive event listeners (addEventListener('touchstart', fn, {passive: true})) tell the browser the listener won't call preventDefault(), allowing scroll optimisation without waiting for JS. 300ms click delay: eliminated in modern browsers; add touch-action: manipulation to CSS as a belt-and-braces fix.
Common Misconception
✗ Click events work fine on mobile — click events on mobile have a 300ms delay on older browsers; click also doesn't fire for swipe gestures. Pointer Events provide immediate response and handle all input types.
Why It Matters
Non-passive touch event listeners block scrolling — the browser must wait for the JS handler before scrolling, causing jank on any page with touch listeners.
Common Mistakes
- Non-passive touchstart/touchmove listeners — causes 50-200ms scroll delay.
- Using touchstart without touchend and touchcancel — incomplete gesture handling.
- Different code paths for touch and mouse — use Pointer Events for unified handling.
- Tap targets under 44x44px — too small for reliable touch input.
Code Examples
✗ Vulnerable
// Blocks scroll — browser waits for JS before scrolling:
document.addEventListener('touchstart', handleTouch);
// Default: {passive: false} — browser must wait for JS
// Separate mouse and touch handlers — maintenance burden:
element.addEventListener('click', handler);
element.addEventListener('touchstart', handler);
✓ Fixed
// Pointer Events — unified, immediate:
document.addEventListener('pointerdown', e => {
if (e.pointerType === 'touch') handleTouch(e);
else handleMouse(e);
});
// Passive scroll listener — does not block scrolling:
document.addEventListener('touchmove', handleMove, { passive: true });
/* CSS — eliminate 300ms delay: */
/* button, a { touch-action: manipulation; } */
// Multi-touch:
document.addEventListener('pointerdown', e => {
activePointers.set(e.pointerId, e); // Track each finger
});
Tags
🤝 Adopt this term
£79/year · your link shown here
Added
16 Mar 2026
Edited
22 Mar 2026
Views
68
🤖 AI Guestbook educational data only
|
|
Last 30 days
Agents 0
No pings yet today
Perplexity 26
Amazonbot 13
ChatGPT 7
Google 4
Unknown AI 3
Ahrefs 3
How they use it
crawler 56
Related categories
⚡
DEV INTEL
Tools & Severity
🟢 Low
⚙ Fix effort: Medium
⚡ Quick Fix
Use Pointer Events API instead of Touch Events — it handles mouse, touch, and stylus with one API; add touch-action: none CSS to elements that handle their own touch to prevent browser interference
📦 Applies To
javascript ES2015
web
🔗 Prerequisites
🔍 Detection Hints
touchstart touchmove touchend without pointer events alternative; 300ms click delay without touch-action CSS; pinch-to-zoom breaking custom gesture handler
Auto-detectable:
✗ No
lighthouse
chrome-devtools
⚠ Related Problems
🤖 AI Agent
Confidence: Low
False Positives: High
✗ Manual fix
Fix: Medium
Context: File
Tests: Update