Best Way to Detect Touch Screen Devices Using JavaScript: For jQuery Desktop & Mobile Plugins
In today’s multi-device landscape, web applications and plugins must seamlessly adapt to both touch-based (mobile, tablets, 2-in-1s) and mouse-based (desktops, laptops) interfaces. Incorrectly detecting touch screens can lead to frustrating user experiences—for example, touch-specific features failing on mobile or mouse-only interactions feeling clunky on touch devices.
JavaScript is the cornerstone of this detection, and with jQuery still widely used for plugin development, understanding how to reliably identify touch screens is critical. This blog will guide you through the most effective methods to detect touch devices using vanilla JavaScript and jQuery, common pitfalls to avoid, and best practices to ensure cross-device compatibility for your desktop and mobile plugins.
Table of Contents#
- Understanding Touch Screen Detection: Why It Matters
- Feature Detection vs. User Agent Sniffing: Which to Choose?
- Vanilla JavaScript Methods for Touch Detection
- 3.1 Checking for
ontouchstartEvent Support - 3.2 Using
Navigator.maxTouchPoints - 3.3 Leveraging the Pointer Events API
- 3.1 Checking for
- jQuery-Specific Approaches for Plugins
- 4.1 Creating a jQuery Utility for Touch Detection
- 4.2 Integrating Touch Detection into jQuery Plugins
- Common Pitfalls to Avoid
- Best Practices for Reliable Detection
- Conclusion
- References
Understanding Touch Screen Detection: Why It Matters#
Touch screen detection is crucial for tailoring user interactions. For example:
- Mobile plugins may require swipe gestures or larger touch targets, while desktop plugins might rely on hover effects or precise clicks.
- Incorrect detection can lead to:
- Touch users missing hover-only features.
- Mouse users experiencing delayed clicks due to touch event handlers.
Thus, accurate detection ensures your jQuery plugins (and vanilla JS code) behave intuitively across devices.
Feature Detection vs. User Agent Sniffing: Which to Choose?#
Before diving into methods, it’s critical to distinguish between two approaches:
User Agent Sniffing#
This involves checking the navigator.userAgent string for keywords like "Mobile", "Android", or "iOS". However, it’s highly unreliable because:
- User agents can be spoofed.
- New devices/browsers emerge constantly (e.g., foldables, 2-in-1s).
- Many desktop browsers now run on touch-enabled devices (e.g., Chrome on Windows tablets).
Example of bad practice (avoid):
// Unreliable!
if (navigator.userAgent.match(/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/)) {
// Assume touch device
}Feature Detection#
This checks for the presence of touch-specific features (e.g., touch events, touch points) rather than relying on device names. It’s future-proof and accurate because it adapts to the device’s capabilities, not its brand.
Example of good practice:
// Check for touch event support
if ('ontouchstart' in window) {
// Likely a touch device
}Verdict: Always use feature detection.
Vanilla JavaScript Methods for Touch Detection#
Let’s explore the most reliable vanilla JS techniques for detecting touch support.
3.1 Checking for ontouchstart Event Support#
Older browsers (e.g., iOS Safari, Android Browser) expose touch events like touchstart, touchmove, and touchend. Checking if the ontouchstart property exists on the window object is a quick way to detect basic touch support.
Code Example:
function isTouchDevice() {
return 'ontouchstart' in window || navigator.maxTouchPoints > 0;
}
// Usage
if (isTouchDevice()) {
console.log("Touch device detected (via ontouchstart)");
}Caveats:
- Some non-touch devices (e.g., certain laptops with touchscreens) may still expose
ontouchstart. - Older browsers (e.g., IE11) do not support
ontouchstart.
3.2 Using Navigator.maxTouchPoints#
The navigator.maxTouchPoints property (part of the W3C Touch Events spec) returns the maximum number of simultaneous touch points the device supports. A value > 0 indicates touch capability.
Code Example:
function isTouchDevice() {
return navigator.maxTouchPoints > 0;
}
// Usage
if (isTouchDevice()) {
console.log("Touch device detected (via maxTouchPoints)");
}Advantages:
- Supported in modern browsers (Chrome, Firefox, Edge, Safari 13+).
- More precise than
ontouchstart(e.g., 2-in-1 laptops with touch screens returnmaxTouchPoints > 0).
Caveats:
- Not supported in IE11 or very old browsers (e.g., Safari < 13).
3.3 Leveraging the Pointer Events API#
The Pointer Events API unifies touch, mouse, and stylus inputs into a single event model (e.g., pointerdown, pointermove). It’s the most modern and reliable way to handle cross-input interactions.
To detect touch support via Pointer Events, check if the browser supports PointerEvent and if the primary pointer type is touch.
Code Example:
function isTouchDevice() {
if (window.PointerEvent) {
// Check if the primary input is touch
return window.matchMedia('(pointer: coarse)').matches;
}
// Fallback for older browsers
return 'ontouchstart' in window || navigator.maxTouchPoints > 0;
}
// Usage
if (isTouchDevice()) {
console.log("Touch device detected (via Pointer Events)");
}Key Concept: (pointer: coarse) is a media query that matches devices with imprecise pointers (e.g., fingers on a touch screen), while (pointer: fine) matches precise inputs (e.g., a mouse).
Advantages:
- Works for hybrid devices (e.g., 2-in-1s) by adapting to the active input method (touch vs. mouse).
- Standardized and supported in all modern browsers (Chrome 55+, Firefox 59+, Edge 12+).
jQuery-Specific Approaches for Plugins#
jQuery simplifies DOM manipulation and event handling, making it popular for plugin development. Here’s how to integrate touch detection into jQuery workflows.
4.1 Creating a jQuery Utility for Touch Detection#
jQuery allows you to extend its utility methods (via $.fn or $.extend) to add custom touch detection.
Example: Custom jQuery Touch Detector
// Add a touch detection method to jQuery
$.extend({
isTouchDevice: function() {
return (
'ontouchstart' in window ||
navigator.maxTouchPoints > 0 ||
(window.PointerEvent && window.matchMedia('(pointer: coarse)').matches)
);
}
});
// Usage in your plugin
if ($.isTouchDevice()) {
console.log("jQuery detected touch device");
// Enable touch-specific logic (e.g., swipe gestures)
} else {
// Enable mouse-specific logic (e.g., hover effects)
}4.2 Integrating Touch Detection into jQuery Plugins#
When building plugins, use jQuery’s event system to handle touch and mouse inputs conditionally.
Example: Touch-Aware jQuery Plugin
(function($) {
$.fn.myPlugin = function(options) {
const settings = $.extend({
touchSensitivity: 50, // Pixels for swipe detection
hoverColor: '#ff0000' // Color for mouse hover
}, options);
return this.each(function() {
const $element = $(this);
const isTouch = $.isTouchDevice(); // Use our utility method
if (isTouch) {
// Bind touch events
$element.on('touchstart', function(e) {
const startX = e.originalEvent.touches[0].clientX;
$element.on('touchmove', function(e) {
const endX = e.originalEvent.touches[0].clientX;
if (Math.abs(endX - startX) > settings.touchSensitivity) {
$element.trigger('swipe', [endX > startX ? 'right' : 'left']);
}
});
}).on('touchend', function() {
$element.off('touchmove'); // Cleanup
});
} else {
// Bind mouse events
$element.hover(
function() { $(this).css('color', settings.hoverColor); },
function() { $(this).css('color', 'initial'); }
);
}
});
};
})(jQuery);
// Usage
$('.my-element').myPlugin({ touchSensitivity: 30 });Common Pitfalls to Avoid#
1. False Positives (Dual-Input Devices)#
Devices like 2-in-1 laptops (e.g., Microsoft Surface) support both touch and mouse. Relying on a single detection method may misclassify them.
Fix: Combine methods (e.g., maxTouchPoints + Pointer Events media queries) to handle hybrid devices.
2. Ignoring Pointer Events#
Using separate touchstart and click events can cause delays or duplicate actions (e.g., a touch triggering both touchstart and click).
Fix: Use Pointer Events (pointerdown, pointerup) instead, which unify touch and mouse inputs:
// Better: Use Pointer Events
$element.on('pointerdown', function(e) {
if (e.pointerType === 'touch') {
// Handle touch input
} else if (e.pointerType === 'mouse') {
// Handle mouse input
}
});3. Overlooking Older Browsers#
Methods like maxTouchPoints or Pointer Events aren’t supported in legacy browsers (e.g., IE11).
Fix: Add fallbacks for older browsers using ontouchstart and feature checks:
function isTouchDevice() {
// Legacy fallback for IE11
if (navigator.msMaxTouchPoints) {
return navigator.msMaxTouchPoints > 0;
}
// Modern checks
return (
'ontouchstart' in window ||
navigator.maxTouchPoints > 0 ||
(window.PointerEvent && window.matchMedia('(pointer: coarse)').matches)
);
}Best Practices for Reliable Detection#
-
Combine Multiple Methods
No single method is foolproof. Use a combination ofmaxTouchPoints, Pointer Events, andontouchstartfor broad coverage. -
Prefer Pointer Events for Input Handling
Instead of separatetouchandmouseevents, usepointerdown,pointermove, andpointerupto handle all input types uniformly. -
Test on Real Devices
Emulators (e.g., Chrome DevTools) are useful, but real devices (especially 2-in-1s and older models) reveal edge cases. -
Avoid Hardcoding Device Behaviors
Don’t assume "touch = mobile" or "mouse = desktop". A 27-inch touchscreen monitor is a desktop device with touch support! -
Update Detection Logic Regularly
Browser support evolves (e.g., new Pointer Events features). Check caniuse.com for the latest stats.
Conclusion#
Detecting touch screens in JavaScript (and jQuery) requires a strategic, feature-based approach. By combining maxTouchPoints, Pointer Events, and legacy ontouchstart checks, you can reliably identify touch capabilities across devices. For jQuery plugins, extend jQuery’s utility methods to integrate detection seamlessly, and use Pointer Events to unify input handling.
Remember: the goal is to create plugins that adapt to the user’s input method, not their device type. With careful testing and these best practices, your code will work intuitively—whether the user is tapping a phone or clicking a mouse.