jQuery Mobile Touch Events (and the Modern Replacements)

Blog / JavaScript · March 28, 2014 · Updated June 10, 2026 · 9 min read
jQuery Mobile Touch Events (and the Modern Replacements)

jQuery Mobile is deprecated and archived — do not build new touch interactions on it. The modern way is the Pointer Events API (with touch-action CSS), or raw Touch events when you need fine control. If you are maintaining legacy code that still calls tap, taphold, swipe, swipeleft, swiperight or the vmouse helpers, this guide explains what each event did and gives you a drop-in replacement using web platform APIs that ship in every current browser.

The jQuery Mobile project was sunset by its team. Its final line was 1.4.x with a 1.5.0-rc1 candidate that never shipped as a stable release, and the project was officially archived (end-of-life notices landed around 2021). It is no longer maintained, gets no security fixes, and assumes a mobile-web landscape from the early 2010s. New code should use the standards-based events below instead.

Key takeaways

  • jQuery Mobile is end-of-life. It is archived, unmaintained, and should not be chosen for new projects in 2026.
  • Use the Pointer Events API for new code. pointerdown / pointermove / pointerup / pointercancel is one unified model for touch, mouse and pen, supported across all modern browsers.
  • Pair pointer events with the touch-action CSS property to control scrolling/zooming, and register listeners as { passive: true } so scrolling stays smooth.
  • Raw Touch events (touchstart / touchmove / touchend) still work and are useful for multi-touch, but you must compute gestures like swipe yourself.
  • You rarely need a library. Detecting a swipe is a few lines of vanilla JavaScript; Hammer.js, the classic gesture library, is now largely unmaintained.
  • CSS often replaces JS gestures entirelyscroll-snap, overflow carousels and the :active pseudo-class handle many interactions with no script at all.

What were jQuery Mobile touch events?

jQuery Mobile added a set of synthetic, normalized touch events on top of jQuery's event system so a single handler worked across the fragmented mobile browsers of its era. The events most people used were:

  1. tap — fires on a quick touch-and-release on an element (the touch equivalent of a click).
  2. taphold — fires when the user presses and holds for roughly 750ms (a long-press).
  3. swipe — fires when the user drags horizontally more than ~30px within a time threshold.
  4. swipeleft / swiperight — the directional variants of swipe.
  5. vmouse* — "virtual mouse" events (vclick, vmousedown, vmousemove, vmouseup) that abstracted over touch vs mouse so one handler covered both input types.

A typical legacy handler looked like this.

// LEGACY jQuery Mobile — deprecated, for reference only.
$(document).on('pagecreate', '#page1', function () {
  // quick tap
  $('p').on('tap', function () {
    $(this).hide();
  });

  // long-press
  $('p').on('taphold', function () {
    $(this).addClass('held');
  });

  // horizontal swipe (and directional variants)
  $('p').on('swipeleft', function () {
    $('span').text('swiped left');
  });
  $('p').on('swiperight', function () {
    $('span').text('swiped right');
  });
});

That code depends on jquery.mobile-1.4.5.min.js, which itself depends on an old jQuery 1.x core. Loading two unmaintained libraries just to detect a tap is exactly the weight modern apps should shed. The good news: every gesture above has a first-class web platform replacement.

jQuery Mobile vs Pointer Events vs Touch events vs a gesture library

Use this table to decide what to reach for. For almost all new work in 2026 the answer is Pointer Events.

Approach Status (2026) Browser support Unified input (touch/mouse/pen) Best for
jQuery Mobile touch (tap/swipe) Deprecated, archived, EOL Needs old jQuery 1.x Yes (synthetic) Nothing new — legacy maintenance only
Pointer Events API Standard, recommended All modern browsers (Chrome, Edge, Firefox, Safari) Yes, natively New projects; one handler for all inputs
Raw Touch events Standard, supported All mobile + most desktop No (touch only; pair with mouse events) Multi-touch, custom pinch/rotate, fine control
Gesture library (Hammer.js, etc.) Hammer.js largely unmaintained Depends on lib Varies Complex gesture sets — prefer a maintained lib or none

How do I replace tap and taphold?

A tap is just a click on touch devices — modern browsers already fire click on tap with no 300ms delay (the old click-delay was removed years ago once a responsive viewport meta tag is set). So replace tap with a plain click listener. For a long-press (taphold), use Pointer Events and a timer.

// MODERN — replaces $('p').on('tap', ...)
const el = document.querySelector('p');
el.addEventListener('click', () => {
  el.hidden = true;
});

// MODERN — replaces $('p').on('taphold', ...) using Pointer Events
const LONG_PRESS_MS = 600;
let pressTimer = null;

el.addEventListener('pointerdown', () => {
  pressTimer = window.setTimeout(() => {
    el.classList.add('held'); // long-press fired
  }, LONG_PRESS_MS);
});

// cancel if the finger lifts, leaves, or the gesture is interrupted
for (const evt of ['pointerup', 'pointerleave', 'pointercancel']) {
  el.addEventListener(evt, () => {
    window.clearTimeout(pressTimer);
  });
}

Note pointercancel: the browser fires it when it takes over the gesture (for example, the user starts scrolling). Always clear timers and reset state on pointercancel or your handler will get stuck in a half-finished gesture.

How do I detect a swipe without jQuery?

This is the big one. To replace swipeleft / swiperight, record where the pointer went down, where it came up, and how long it took, then check the horizontal distance against a threshold. The snippet below is a complete vanilla replacement for $(el).on('swipeleft swiperight', ...) — no library required.

// MODERN vanilla swipe detection — replaces jQuery Mobile swipeleft/swiperight.
// Uses Pointer Events so it works for touch, mouse drag and pen.
function onSwipe(el, handlers = {}) {
  const THRESHOLD = 30;   // px of horizontal travel (jQuery Mobile used ~30)
  const MAX_OFF_AXIS = 60; // ignore if it's really a vertical scroll
  const MAX_TIME = 700;    // ms — a swipe is a fast flick, not a slow drag
  let startX = 0, startY = 0, startT = 0, tracking = false;

  el.addEventListener('pointerdown', (e) => {
    tracking = true;
    startX = e.clientX;
    startY = e.clientY;
    startT = e.timeStamp;
  });

  el.addEventListener('pointerup', (e) => {
    if (!tracking) return;
    tracking = false;
    const dx = e.clientX - startX;
    const dy = e.clientY - startY;
    const dt = e.timeStamp - startT;
    if (dt > MAX_TIME) return;
    if (Math.abs(dy) > MAX_OFF_AXIS) return; // too vertical — not a swipe
    if (Math.abs(dx) < THRESHOLD) return;    // didn't travel far enough
    if (dx < 0) handlers.left?.(e);
    else handlers.right?.(e);
  });

  el.addEventListener('pointercancel', () => { tracking = false; });
}

// usage
const box = document.querySelector('#card');
onSwipe(box, {
  left: () => console.log('swiped left'),
  right: () => console.log('swiped right'),
});

Two details that make this production-ready:

  • Set touch-action in CSS on the swipe target so the browser does not also scroll/zoom while you are reading the gesture. For a horizontal swipe inside a vertically scrolling page, use touch-action: pan-y;. To fully own the gesture, use touch-action: none;.
  • Register move listeners as passive when you only read coordinates (el.addEventListener('pointermove', fn, { passive: true })). Passive listeners let the browser scroll on the compositor thread, which keeps the page at 60fps.
/* CSS that pairs with the swipe handler above */
#card {
  /* allow vertical page scroll, but let JS own horizontal swipes */
  touch-action: pan-y;
}

/* a horizontal, snap-to-card carousel with ZERO JavaScript */
.carousel {
  display: flex;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
}
.carousel > .slide {
  flex: 0 0 100%;
  scroll-snap-align: start;
}

When should I use raw Touch events or a library?

Reach past Pointer Events only when you have a specific need:

  • Raw Touch events (touchstart / touchmove / touchend / touchcancel) expose a TouchList of every finger on the screen via event.touches. If you are building pinch-to-zoom, two-finger rotate, or anything genuinely multi-touch, the Touch events model is the most direct tool. The trade-off is that touch events only cover touch — you would still wire up mouse/pen separately, which is exactly the duplication Pointer Events removes.
  • Gesture libraries make sense for large, complex gesture sets you do not want to hand-roll. But be careful what you adopt: Hammer.js, the library most tutorials reach for, has been effectively unmaintained for years. If you genuinely need a library, pick one that is actively maintained and that delegates to Pointer Events under the hood; otherwise prefer the vanilla approach above.
  • Modern frameworks (React, Svelte, Vue) all expose pointer events directly in their templates (onPointerDown, on:pointerdown), so the same standards-based model works inside a component tree with no extra dependency.

In short: Pointer Events first, raw Touch events for true multi-touch, CSS for scroll-style gestures, and a library only as a last resort.

Migrating a legacy jQuery Mobile app

If you have inherited a jQuery Mobile codebase, you do not have to rewrite everything at once. A pragmatic path:

  1. Inventory the gestures actually in use — grep for .on('tap', taphold, swipe, and vmouse across the project. Most apps use only tap and swipe.
  2. Replace tap with click and taphold/swipe with the Pointer Events snippets above. These have no external dependency and can land file-by-file.
  3. Drop the jQuery Mobile CSS framework (its data-role widgets, theming and page transitions) in favor of plain semantic HTML plus your own CSS or a modern component library.
  4. Remove jQuery Mobile and, once nothing else needs it, jQuery itself from the bundle. Modern DOM APIs (querySelector, classList, fetch) cover what jQuery core was used for.

This kind of incremental deprecation rescue — peeling an app off an end-of-life framework without a risky big-bang rewrite — is the bread and butter of the web development and React development work we do at MicroPyramid. For deeper background on how jQuery itself handles input, see our companion guides on jQuery mouse and touch events and event delegation in jQuery, and on where the library is headed in jQuery features overview and its future.

Frequently Asked Questions

Is jQuery Mobile still supported in 2026?

No. jQuery Mobile is deprecated, archived and end-of-life. The project was sunset by its maintainers, its last line was 1.4.x (with a 1.5.0-rc1 that never shipped stable), and it receives no further updates or security fixes. Do not start new projects on it; migrate existing ones to standards-based events.

What should I use instead of jQuery Mobile touch events?

Use the Pointer Events API (pointerdown / pointermove / pointerup / pointercancel) for new code. It is a single, standardized model that handles touch, mouse and pen with one set of handlers, is supported in every modern browser, and pairs with the touch-action CSS property to control scrolling and zoom.

How do I detect a swipe without jQuery Mobile?

Track the pointer position on pointerdown and pointerup, then compare the horizontal distance (deltaX) and elapsed time against thresholds — roughly 30px of travel within ~700ms counts as a swipe. If deltaX is negative it is a left swipe, positive is a right swipe. The vanilla onSwipe helper in this article is a complete drop-in replacement for swipeleft/swiperight.

What is the difference between Pointer Events and Touch events?

Pointer Events unify all input types (touch, mouse, pen) behind one event model, so you write a handler once. Raw Touch events only cover touch and expose every finger on screen through a TouchList, which makes them better for genuine multi-touch gestures like pinch-to-zoom — but you would have to add separate mouse handlers for desktop. For most apps, Pointer Events are simpler and sufficient.

Should I still use Hammer.js for gestures?

Probably not. Hammer.js has been effectively unmaintained for years, and most gestures it provided are now a few lines of Pointer Events code. Reach for a library only for large, complex gesture sets, and choose one that is actively maintained and built on Pointer Events. For tap, long-press and swipe, vanilla code is lighter and has no dependency risk.

Why did the 300ms tap delay exist and is it gone?

Old mobile browsers waited ~300ms after a tap to see whether you were double-tapping to zoom, which made taps feel laggy — one reason jQuery Mobile's synthetic tap event was popular. Modern browsers removed that delay for pages that declare a responsive viewport (<meta name="viewport" content="width=device-width, initial-scale=1">), so a plain click listener now responds instantly on touch.

Share this article