← Home ← Codex ← DEBT
Browse by Category
+ added · updated 7d
← Back to glossary

Touch Events & Pointer Events

Mobile ES2015 Intermediate
debt(d7/e3/b3/t7)
d7 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'only careful code review or runtime testing' (d7). The detection_hints list Lighthouse and Chrome DevTools, and automated is marked 'no'. Lighthouse can flag non-passive listeners as a performance audit, but this is a specialist audit tool that only surfaces issues during profiling or an explicit audit run — not during normal development or standard linting. The jank and 300ms delay are only noticeable at runtime on actual touch devices.

e3 Effort Remediation debt — work required to fix once spotted

Closest to 'simple parameterised fix' (e3). The quick_fix describes switching to Pointer Events API and adding touch-action CSS — this is a targeted refactor within affected components. It's more than a single-line swap because event handler names change and touch-action CSS must be added to relevant elements, but it doesn't span the entire codebase if touch listeners are reasonably localized.

b3 Burden Structural debt — long-term weight of choosing wrong

Closest to 'localised tax' (b3). Applies only to web contexts with touch/pointer handling code. Components with custom gesture handling pay the tax (incomplete handling, passive listener boilerplate), but the rest of the codebase is unaffected. It doesn't impose a system-wide architectural cost.

t7 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'serious trap' (t7). The misconception field explicitly states that developers believe 'click events work fine on mobile,' which directly contradicts reality — click has a 300ms delay and doesn't fire for swipe gestures. This is a cross-platform behavioral difference (desktop vs. mobile) that a competent developer familiar with desktop web development would naturally get wrong. The non-passive listener scroll-blocking behavior compounds the trap.

About DEBT scoring →

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
});

Added 16 Mar 2026
Edited 22 Mar 2026
Views 135
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings T 0 pings W 0 pings T 1 ping F 1 ping S 5 pings S 3 pings M 2 pings T 2 pings W 2 pings T 3 pings F 1 ping S 0 pings S 1 ping M 1 ping T 0 pings W 1 ping T 2 pings F 3 pings S 1 ping S 0 pings M 1 ping T 0 pings W 0 pings T 2 pings F 0 pings S 1 ping S 0 pings M 0 pings T 0 pings W
No pings yet today
No pings yesterday
ChatGPT 32 Perplexity 27 Amazonbot 16 Google 7 Ahrefs 5 Unknown AI 3 SEMrush 3 Claude 2 Scrapy 2 Bing 1 Meta AI 1 Qwen 1 Sogou 1
crawler 97 crawler_json 4
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


✓ schema.org compliant