FastClick.js (more like Thing-of-the-Past-Click.js)

17 Oct 2017

<select> elements have always been kind of awkard, IMO.

web-bug 12553 describes an issue where a pretty famous 3rd party library, FastClick.js turns <select>-level awkward to middle-school-dance-party-level awkward.

(In that the <select> doesn’t function at all if you’re on Android, unless you’re using Chrome Mobile (depending on what FastClick version you’re running). Just like middle school—trust me this analogy makes total sense, 7th grade was really hard for me and I’m still working through it, OK.)

The issue here is the result of a web standards interoperability failure (more on that in a second, there’s a happy ending I swear) and the inability to predict the future of the web platform and browsers by FastClick (more on that now).

So if you don’t know much about FastClick, or why it was so popular, put on 2012’s “Now That’s What I Call Music! Volume 44” to set the mood and read their GitHub page.

Cover of Now Thats What I Call Music Volume 44 album

Back in 2012, when tapping on things in mobile browsers was slow (because browsers always had a 300ms delay between a touchend event and a click event), it was cool to use FastClick to make tapping on things fast. Noted soda water critic Jake Archibald has a good article on this and how to get rid of it these days (tl;dr make your site’s viewport mobile friendly).

(The article is a bit dated given that Firefox didn’t support touch-action: manipulation when it was authored, but it does now, so consider that another option.)

OK, so. Anyways. The way this library works is to dispatch its own synthetic click event after a touchend event, without the 300ms delay. This is all great and fine for links. Things get trickier for inputs like <select>, because there’s never really been a web standards way to programatically open them via JS.

Per DOM level 3(000), untrusted events (think event.isTrusted == false…except for click) shouldn’t trigger the default action. And the default action for <select> is to open the widget thingy and display the 400 countries you don’t live in.

OK, back to FastClick in the year 2012. Things either broke on <select> elements, or never worked properly in Chrome Mobile, but developers (being developers) found a workaround with mousedown events for Chrome Mobile (in a stackoverflow thread, naturally), put it into FastClick. This unintentionally broke it for other browsers, and later on some fixes were introduced to unbreak that for Firefox and Blackberry. But… that’s only some of the select-related bugs.

Fast foward a few years and Chrome fixed their untrusted events default action bug, and as a result broke <select>s on pages using FastClick. Fortunately for interop, they decided to not back out the fix (except for Android WebView!).

Anyways, this blog post is getting too long.

In conclusion, if you run into bugs with FastClick, you should probably delete it from your app. It’s basically unmaintained and they don’t want you to use it either.

And besides, we have touch-action: manipulation anyways.