Faster Tapping with SwiftClick


SwiftClick is a library created to eliminate the 300ms click event delay on touch devices that support orientation change and is designed to be super lightweight — weighing in at only 957 bytes minified & gzipped!

As many of you will have experienced when using touch devices such as iPhones, tapping on HTML elements sometimes feels a bit sluggish. This is because there is a 300ms delay before click events are fired. As a user experience this is clunky behaviour and so the exploration of potential solutions to this problem worked its way into TMW labs. Since the issue only occurs on devices that support touch events, the initial approach was to simply run a basic test for touch support and create a variable for the event name to use in click listeners – the value of which being either 'touchstart' for devices that support touch, or 'click' for those that don't:

var clickEventType = "ontouchstart" in window ? "touchstart" : "click";

The problem with this detection method is that laptops or monitors that support touch would expect a touch event, meaning that if a mouse was being used then click events wouldn't work. Because of this the detection method was refined to check if the device supports both touch and orientation change and only use touch events if both conditions are met:

var clickEventType = "onorientationchange" in window && "ontouchstart" in window ? "touchstart" : "click";

This detection method worked well in the majority of situations, with the 'clickEventType' variable being used in any event listeners that needed to get a click event:

someEl.addEventListener(clickEventType, fn, false);

This worked pretty nicely, with the main drawback being the fact that the 'clickEventType' variable would have to be used in any place where a click listener is needed, which could potentially become problematic when projects are picked up by new developers who may not necessarily realise that this variable is being used at all.

Other options were explored, including a really nice utility called FastClick, developed by FT Labs. When an HTML element is touched, FastClick hijacks the touch event and creates a synthesised click event if necessary, which is then dispatched by the touched element. This allows JavaScript event listeners to be registered using the normal 'click' event type, but has the advantage of these events being fired earlier than normal – effectively removing the 300ms delay. For the most part this worked really well, but it eventually became apparent that the util sometimes exhibited strange behaviour, such as ghost-clicks, or events not firing at all when links were clicked and then firing later on, at the same time as other click events when different elements were clicked. And at 25kb non-minified (2.4kb minified & gzipped) it is also a bit heavy in file size when considering the nature of the task for which it was created to solve. Therefore, the time was right to create a custom solution – SwiftClick.

SwiftClick is inspired by FastClick, but has been designed from the ground up to be super lightweight — weighing in at a mere 6.8KB non-minified and a teeny-tiny 957 bytes (yes, bytes) minified & gzipped!

In contrast with FastClick, which does a lot under the hood to fix obscure bugs in many crappy old mobile browsers for complex elements like <form>, <select>, and <textarea>, by default SwiftClick focuses on basic element types that are typically used in modern interactive development, providing an option to add in additional element types when necessary.

Usage

Firstly, grab either the minified, or non-minified source from Github, or install via Bower using the following command in your command prompt:

bower install swiftclick

Include SwiftClick in your application

<script type="application/javascript" src="path/to/swiftclick.min.js"></script>

Setup SwiftClick

Setting up SwiftClick is a very easy process, which mirrors that of FastClick in that instances must be attached to a context element. Touch events from all elements within the context element are automatically captured and converted to click events when necessary, minus the delay.

Start by creating a reference to a new instance of SwiftClick using the 'attach' helper method and attach it to a context element. Attaching to document.body is easiest if you only need a single instance of SwiftClick:

var swiftclick = SwiftClick.attach(document.body);

If necessary, multiple instances of SwiftClick can be created for specific context elements which, although not really necessary in most cases, can sometimes be useful for optimising applications with a large amount of HTML:

var navigationSwiftClick = SwiftClick.attach(someNavElement);
var uiSwiftClick = SwiftClick.attach(someOtherElement);

Default Elements

Once attached, by default SwiftClick will track events originating from the following element types:

  • <a>
  • <div>
  • <span>
  • <button>

Adding non-default element types

If necessary you can make SwiftClick track events originating from additional element types by adding an array of node names. This requires a reference to an instance of SwiftClick:

var swiftclick = SwiftClick.attach(someElement);
swiftclick.addNodeNamesToTrack(["p", "h1", "nav"]);

Replacing all stored node names to track

var swiftclick = SwiftClick.attach(someElement);
swiftclick.replaceNodeNamesToTrack(["a", "div"]);

Doing this will remove all default node names, as well as any that have been added, and replace them with the node names within the array that is passed in, resulting in only the new node names being tracked.

Automatically disabled when not needed

SwiftClick only intercepts events for touch devices that support orientation change, otherwise it just sits there looking pretty.

About the Project

SwiftClick was developed and is currently maintained by Ivan Hayes.

Head over to the Github project page to find out more. Go ahead and star the project to keep up with its latest developments :-)