When designing a responsive site for mobile you want it to feel as quick and fluid as a native app would. We recently came across an issue that left our web application feeling slow and cheap. We tracked the problem down to the way we were handling click events in our single page application. Using jQuery’s click event or the native javascript onclick handler works great until you get to touch devices.
Why the Problem?
Originally, touch devices came out with a feature known as double-tap to zoom. This was before the days of responsive/mobile friendly sites, so zoom was a very common action. In order to differentiate between a single tap and a double-tap to zoom, a delay of ~300ms was added after the initial click/tap to listen for a second click/tap. Therefore, a single click event now took ~300ms longer than before, resulting in a sluggish user experience.
Interactive Demo
The following is an interactive demo comparing the response times of several events. Please try this out on a mobile/touch device to see the difference! (I can add other events/libraries to this demo upon request)
Interactive JSFiddle
Possible Solutions
FastClick.js
The first (and possibly easiest) solution is to simply add the FastClick library to your project. FastClick allows you to eliminate the 300ms delay without making any modifications to your existing code. This means that you do not have to update your event handlers or even the events you are binding to.if ('addEventListener' in document) {
document.addEventListener('DOMContentLoaded', function() {
FastClick.attach(document.body);
}, false);
}
// OR if your using jQuery
$(function() {
FastClick.attach(document.body);
});
Tap.js
There are a several libraries out there that implement a tap event, but Tap.js is the one i would recommend. Instead of attaching click events to your DOM objects, you will now attach tap events. This requires a small modification to existing code, but not much. Tap events will now work using a mouse on desktop or a touch on mobile. Why would you choose this over FastClick? I would say the size of the library is enough reason (~1KB vs the ~8KB of FastClick at the time of this writing).document.getElementById('any-element').addEventListener('tap', function (e) {
// Proceed as usual
});
// OR if using jQuery
$('#any-element').on('tap', function (e) {
// Proceed as usual
});
Hammer.js
Hammer.js is another library that implements a tap event, but also provides several other touch gestures in a relatively small package (< 4KB). This library would require a little more modification to existing code, but is definitely worth it if you need events such as swipe, rotate, pinch, etc.var hammertime = new Hammer( myElement, myOptions );
hammertime.on( 'tap', function( event ) {
// Proceed with the goods
});
// OR if using jQuery (Note: this requires an additional plugin)
$( element ).hammer( options ).bind( "tap", function( event ){
// Proceed with the goods
});
No Library?
This has been a problem for some time, and some browsers have already implemented a fix. Unfortunately, these are browser specific fixes. For example, Google Chrome removed the 300ms delay by adding the following meta tag to your page. The browser then disables the double-tap to zoom, effectively eliminating the need for a delay.<meta name="viewport" content="width=device-width, user-scalable=no">
The above fix for Chrome does not work on Windows touch devices, but apparently the following css will remove the delay.
html {
-ms-touch-action: manipulation;
touch-action: manipulation;
}
The original goal was to make our web applications fast and responsive on mobile devices. For your benefit, here is a link to a production site that makes use of the FastClick.js library: seattleiteguide.com. Feel free to check out how it responds to click events on your favorite mobile device!