Coder Social home page Coder Social logo

fastclick's Introduction

FastClick

FastClick is a simple, easy-to-use library for eliminating the 300ms delay between a physical tap and the firing of a click event on mobile browsers. The aim is to make your application feel less laggy and more responsive while avoiding any interference with your current logic.

FastClick is developed by FT Labs, part of the Financial Times.

Note: As of late 2015 most mobile browsers - notably Chrome and Safari - no longer have a 300ms touch delay, so fastclick offers no benefit on newer browsers, and risks introducing bugs into your application. Consider carefully whether you really need to use it.

Explication en français.

日本語で説明

Why does the delay exist?

According to Google:

...mobile browsers will wait approximately 300ms from the time that you tap the button to fire the click event. The reason for this is that the browser is waiting to see if you are actually performing a double tap.

Compatibility

The library has been deployed as part of the FT Web App and is tried and tested on the following mobile browsers:

  • Mobile Safari on iOS 3 and upwards
  • Chrome on iOS 5 and upwards
  • Chrome on Android (ICS)
  • Opera Mobile 11.5 and upwards
  • Android Browser since Android 2
  • PlayBook OS 1 and upwards

When it isn't needed

FastClick doesn't attach any listeners on desktop browsers.

Chrome 32+ on Android with width=device-width in the viewport meta tag doesn't have a 300ms delay, therefore listeners aren't attached.

<meta name="viewport" content="width=device-width, initial-scale=1">

Same goes for Chrome on Android (all versions) with user-scalable=no in the viewport meta tag. But be aware that user-scalable=no also disables pinch zooming, which may be an accessibility concern.

For IE11+, you can use touch-action: manipulation; to disable double-tap-to-zoom on certain elements (like links and buttons). For IE10 use -ms-touch-action: manipulation.

Usage

Include fastclick.js in your JavaScript bundle or add it to your HTML page like this:

<script type='application/javascript' src='/path/to/fastclick.js'></script>

The script must be loaded prior to instantiating FastClick on any element of the page.

To instantiate FastClick on the body, which is the recommended method of use:

if ('addEventListener' in document) {
	document.addEventListener('DOMContentLoaded', function() {
		FastClick.attach(document.body);
	}, false);
}

Or, if you're using jQuery:

$(function() {
	FastClick.attach(document.body);
});

If you're using Browserify or another CommonJS-style module system, the FastClick.attach function will be returned when you call require('fastclick'). As a result, the easiest way to use FastClick with these loaders is as follows:

var attachFastClick = require('fastclick');
attachFastClick(document.body);

Minified

Run make to build a minified version of FastClick using the Closure Compiler REST API. The minified file is saved to build/fastclick.min.js or you can download a pre-minified version.

Note: the pre-minified version is built using our build service which exposes the FastClick object through Origami.fastclick and will have the Browserify/CommonJS API (see above).

var attachFastClick = Origami.fastclick;
attachFastClick(document.body);

AMD

FastClick has AMD (Asynchronous Module Definition) support. This allows it to be lazy-loaded with an AMD loader, such as RequireJS. Note that when using the AMD style require, the full FastClick object will be returned, not FastClick.attach

var FastClick = require('fastclick');
FastClick.attach(document.body, options);

Package managers

You can install FastClick using Component, npm or Bower.

For Ruby, there's a third-party gem called fastclick-rails. For .NET there's a NuGet package.

Advanced

Ignore certain elements with needsclick

Sometimes you need FastClick to ignore certain elements. You can do this easily by adding the needsclick class.

<a class="needsclick">Ignored by FastClick</a>

Use case 1: non-synthetic click required

Internally, FastClick uses document.createEvent to fire a synthetic click event as soon as touchend is fired by the browser. It then suppresses the additional click event created by the browser after that. In some cases, the non-synthetic click event created by the browser is required, as described in the triggering focus example.

This is where the needsclick class comes in. Add the class to any element that requires a non-synthetic click.

Use case 2: Twitter Bootstrap 2.2.2 dropdowns

Another example of when to use the needsclick class is with dropdowns in Twitter Bootstrap 2.2.2. Bootstrap add its own touchstart listener for dropdowns, so you want to tell FastClick to ignore those. If you don't, touch devices will automatically close the dropdown as soon as it is clicked, because both FastClick and Bootstrap execute the synthetic click, one opens the dropdown, the second closes it immediately after.

<a class="dropdown-toggle needsclick" data-toggle="dropdown">Dropdown</a>

Examples

FastClick is designed to cope with many different browser oddities. Here are some examples to illustrate this:

Tests

There are no automated tests. The files in tests/ are manual reduced test cases. We've had a think about how best to test these cases, but they tend to be very browser/device specific and sometimes subjective which means it's not so trivial to test.

Credits and collaboration

FastClick is maintained by Rowan Beentje, Matthew Caruana Galizia and Matthew Andrews at FT Labs. All open source code released by FT Labs is licenced under the MIT licence. We welcome comments, feedback and suggestions. Please feel free to raise an issue or pull request.

fastclick's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

fastclick's Issues

Is it possible to have FastClick work with webkit-overflow-scrolling?

FastClick works very well, but when paired with webkit-overflow-scrolling which does the iOS scrolling momentum, the clicks are registered as the elements scroll by.

It would be nice for fast click to wait until the scrolling is finished or stop the scrolling when the user clicks.

Is there a way around this?

iOS input bug - input fields

I've built an application for iOS which implements fastclick. But the app becomes buggy when there are multiple input fields displayed at the same time and the user taps on one of them. E.g: I've a registration form with a few input fields (name, email etc). Tapping a field shifts focus to the wrong input field which quickly becomes very frustating. The keyboard appears at the same time. This generally happens the first time I started googling this issue and found a pretty fresh thread which unfortunately got locked:

#17

You say that you cant reproduce the error but I can. Just open http://jsfiddle.net/agH7R/5/ (which was posted in the former thread) and first press "this is link" and then the input field about. The keyboard shows up but focus is moved up towards the CSS code, it doesnt focus on the input field.

So to sum it up: there is some issues with fastclick ability to determine which input field is clicked, there seem to be problems with setting focus and moving the view to the correct element. Am I the only one who can reproduce this? I've tested it on an iPhone 4 with iOS 5.1.1 and an iPhone 5 with iOS 6.

Do you have any idea how I can troubleshoot this issue?

Issue with iframe on iOS

When used on a page loaded in an iframe, on iOS devices (specifically iPad), inputs dont work. I mean, if the page inside an iframe has an <input type=text>, on iPad when you focus the field the touch keyboard shows up but you cant type.

Incorrect click coordinates on Android Chrome

From @fwebdev, moved from #2:

Clicking on a top right link triggers a link / onclick on the middle of the page.
And somethime a does nothing at all when clicking on a href.

The "fix" is to remove fastclick.js

I tested it on a Samsung Galaxy Acer, Samsung S2 and S3.
All with latest Chrome and Android 4.0.4 up to 4.1

Cannot select text in iOS5

In iOS 5.1, if you create the FastClick on the body, the user is unable to select text.

This is resolved in iOS 6

If there there is a text/number input in focus - fastclicks will not fire subsequently.

In iOS6 - the fix for #49 seems to cause problems when pressing another element on the page when there is a number/text input in focus.

When focussed on a text input field, the window.getSelection().rangeCount will return 1 at this point, the onTouchStart event returns true and the targetElement is not set.

When a text input is selected - the getSelection().type is "Carot", whereas on a standard text selection this is "Range".

Perhaps an extra clause on the if statement would solve this issue. Something like:

// Only trusted events will deselect text on iOS (issue #49)
if (window.getSelection().rangeCount && window.getSelection().type.toLowerCase() === "range") {
    return true;
}

When focus is held by a text input, clicks anywhere near it bring up the keyboard

Test case: http://jsbin.com/imesop/1

With the latest version of the library (and older versions too), I notice the following on Android (not iOS, where "focus" seems to have different semantics anyway). That simple test case illustrates. When the page loads, it explicitly gives focus to the text field. Attempts to click on the radio buttons, or just on white space far from the text field, always bring up the keyboard. Furthermore, the click is apparently not delivered to the radio button (if that's the target). A second click on the radio button works, but the keyboard stays up.

This behavior doesn't seem to have anything to do with whether focus is set programatically. That is, if the JavaScript to focus weren't there, it acts the same way if you click in the text input and then dismiss the keyboard with the device "back" button.

I'm running Chrome on Android 4.0.3. Also see it on the Nexus 7 with Chrome and 4.1. I haven't tried debugging it yet.

Android Chrome clicking 'selects' everything and can't remove

Hey, just noticed, only in Android Chrome, I frequently get this issue where a touch will 'select' the whole div.container, highlighting it all blue, and I can't click out of it. Kind of annoying.

Also, it's all pjax so lots of time i'll click on a button and everything will load right but the button will stay selected until you click off it.

check out www.tagxt.com on android chrome to see what I mean.

Buttons seem to have problems in Chrome on Android 4.1

I'm noticing that when I've got focus in a textarea (I've applied the "needsClick" textarea patch), clicking on a button seems to have no effect. If I run my page without FastClick, it works.

There's not much special about the setup I've got but I'm happy to try and duplicate it.

Adding "button" to the "needsClick" list doesn't help.

iOS input bug

onTouchStart you are calculating element position. onTouchEnd you are getting element by this position. When user focuses input iOs displays keyboard and if input was in the bottom of screen iOs scrolls screen down to make input at the top of screen. So when you are getting element by onTouchStart positions you are obtaining wrong element because original input was scrolled to the top

May be the same bug is presented on Android.

jquery mobile active state sticking after pressing links

I am using jquery mobile 1.1.1 and using latest version of fastclick.js and applying the js globally, The problem occurs when I tap on my menu items, they procede to next page (awesomely fast might I say, great job!) but then when I tap to go back the menu item becomes stuck in an active state, or visited state.

long press and swiping often produces undesired "clicks"

i am mostly loving this code but i noticed that if i lift a finger when on a link it will register as a click without discrimation to my desired action.

often if i am quickly scrolling down a long page, if i happen to be on a link when lifting my finger it will interrupt me and proceed to the link.

also, if i long press on a link to get the 'open in a new window ' dialog, lifting off the link to pick an option immediately just takes me to the link.

not sure if these are really 'bugs' or working as intended and that is the price we pay for fast clicks but they are the only things i've found keeping this from 'perfect'

this is android 4.0 stock and chrome browsers i know of but likely all are affected by this.

thanks!

Can't focus in textarea's on Android Chrome

Hi.

On android chrome browser, it will not focus in any textarea's when using this fastclick code.

Everything is fine on android stock browser and chrome on ipad works fine too.

On android chrome though, it just holds this blue rectangle over the whole textarea and never enters it, giving a cursor or popping up keyboard.

If you long hold on the textarea, it will bring up the two selector icons and let you highlight a word and copy/paste menu, but still no cursor.

standard input type='text'/'password' work fine. just textarea's are effected.

maybe something here will give you an idea how to resolve: http://code.google.com/p/iscroll-js/issues/detail?id=17

thanks!

Recent changes affect Android cursor functionality

i just updated fastclick with the most recent version and noticed it no longer functions correctly on textareas on android phone. before, anf on other sites, if i click in a textarea, it brings up the single blue arrow i can use to move the cursor arround the text box.

now it does not behave this way and single pressing in the textarea does not produce the single blue arrow. long pressing on a word does produce the double blue arrow for word selection, but its currently impossible to move the cursor location using fastclick. you can see examples by using any tagxt.com textareas. this is on chrome/android 4.0.4

Click while scrolling iPhone iOS

fastclick is the best solution to manage clicks on Mobile devices, I have faced one issue which is while scrolling if you set the CSS -webkit-overflow-scrolling : touch it will scroll smooth but when you click it goes to wrong link in case you have a list of links.

This is a link for the issue http://hadi.binhoster.com/gag/

Support advanced compilation with Closure Compiler

Currently reports the following warnings, as well as reducing to nothing because FastClick is not exposed/an extern:

JSC_MISSING_RETURN_STATEMENT: Missing return statement. Function expected to return boolean. at line 127 character 13
onTouchEnd = function(event) {
             ^
JSC_TYPE_MISMATCH: actual parameter 1 of needsClick does not match formal parameter
found   : (Node|null)
required: (Element|null) at line 158 character 15
if (needsClick(targetElement)) {
               ^
JSC_INEXISTENT_PROPERTY: Property ontouchstart never defined on Window at line 227 character 4
if (window.ontouchstart === undefined) {
    ^
JSC_TYPE_MISMATCH: assignment to property onclick of Element
found   : string
required: (function ((Event|null)): ?|null) at line 243 character 0
layer.onclick = '';

Android 2.* support

Hi Chaps,

I notice that you don't advertise support for Android 2.* and I've tried the basic usage example on android 2.3 and 2.2 and it is buggy (box B turns green on clicking but turns white again almost immediately). Just wondering if this is something you're planning on adding?

Cheers

Google Maps tap on Marker does not work

I get this error every time with Google Maps when tap on my iPad on a marker which has a "click" event bound to it. On the desktop it works with a mouse.

TypeError: 'null' is not an object (evaluating 'targetElement.nodeName')

on line 301, at

if (targetElement.nodeName.toLowerCase() === 'label') { ...

I think there is a conflict because the Google Maps v3 Library takes care itself of click/touch events

FastClick prevents zoom on double tap

I am currently toying with implementing FastClick on a website, but during my tests, I found that FastClick disables the default "zoom content on double tap".

When you think about it, it makes sense, that this is what happens, but my question is, can I get the best of both worlds?

Support for double taps to zoom, but still having faster "normal" clicks?

No links working using Firefox 18.0a2 on Win7/64

I'm testing always the newest Browsers. And with fastclick (from 22.10.2012) there in on a page not any link working, using Firefox Aurora 18.0a2 (2012-10-21) .
Firebug show no errors. Using Firefox 16.0.1 there are no problems.

fastclick performance/benchmarks

Does anyone know how to measure the performance boost using fastclick? The goal is to ensure that all click events are actually faster with fastclick.js vs. without (i.e., is it always a 300ms improvement?).

My suggestion is to add some code to the demos that will generate actual times. Seeing the color change to green is sometimes hard to perceive. Also, it would be better to have multiple fastclick buttons in the demo since that is more real-world.

FWIW, I've used a JS microtime() function to analyze speed in other scenarios but I'm not really sure what how this code work with fastclick. I guess otherwise I would be able to open and close this issue myself :).

thanks,
tim

Synthesize mousedown and mouseup events also?

Are there plans to synthesize other events in addition to the click event?

Some UI components rely on other mouse events triggered by the browser before the click event. I use the Yahoo! User Interface Library 2 at work. YUI2's button will not display an attached dropdown menu unless it gets a mousedown and a mouseup event before the click event.

I've reproduced this issue in a JSFiddle. It's a copy-paste of the dropdown menu example from YUI2's documentation (here), with FastClick added. It works fine on a desktop browser. In iPad Safari, however, the buttons don't work unless you long-tap them.
http://jsfiddle.net/cspotcode/kcNs9/

Here's the same thing with mousedown and mouseup events being synthesized, using my fork of fastclick. It works correctly on iPad.
http://jsfiddle.net/cspotcode/zyujM/

Caveats:

  • my code is not tested on many browsers
  • I don't know if it's necessary to suppress mousedown and mouseup events generated by the browser
  • I don't know if/when it would be necessary to synthesize other events, such as mouseover or mouseout

EDIT: forgot to link to my fastclick fork: https://github.com/cspotcode/fastclick

fastclick on document.body shouldn't be the recommended use?

Hi, I put fastclick.js on my site along with the following code (from the fastclick.js README):

window.addEventListener('load', function() {
    new FastClick(document.body);
}, false);

Unfortunately on iOS Safari this produces quite a terrible UX because it seems that all touch events (scroll, swipe, click) trigger fastclick so the UI gets bogged down and my "fast" clicks turn into "slow" clicks.

Might it be better to recommend to people to specify a className that should get fastclicks to narrow down the number of events fastclick has to handle? My main point is to better inform people on how to use fastclick.js correctly.

``` document.getElementsByClassname````

"Slow" tap produces two "click" events on iOS 6

It's kinda hard to describe this. But I will try. If can't be understood I will post a video.

I have a button that will go to a new screen. When I tap the button rather slowly, it will perform the first click event and the screen will change. On the new screen, another click event will be triggered but on a new element (a button which is exactly in the same position as the first button).

This problem doesn't happen if the tap happens quick.

Is this a know bug? I have only experienced so far on iOS 6, Safari.

layer.html example broken on Android

Hi Guys. Good work! Tried the layer.html on iPad and works beautifully.
Viewing demo direct from: http://ftlabs.github.com/fastclick/examples/layer.html

However, there are issues on Android (Samsung Galaxy Nexus running ICS 4.0.4.)

On default Android browser (4.0.4): Layer A responds, Layer B does not respond at all;

On Chrome for Android (18.0.x): Layer A responds, Layer B toggles Layer A's state.

Cheers.

PS. Just tried the older version of FastClick (http://labs.ft.com/wp-content/uploads/2011/08/fastclickdemo.html) and the result is the same. Hope this helps.

No synthetic clicks on elements deep in the DOM hierarchy

From JB:

I'm just getting the overall framework setup and starting to look at the fastclick library you maintain but running into problems when testing on Android browser v4.0.3

Basically it seems to be only triggering the synthetic click event on links in the top level navigation. Any links found inside the second level (several nested UL's) just trigger the native click (after the 300ms delay).

The way I have found to resolve this when instantiating Fastclick to pass just 'document' as the layer argument, instead of 'document.body'. Or, if I create an empty event listener on document ontouchstart when my app initialises, that also fixes it (without having to use document.body when instantiating Fastclick.

Hover state support

Tapping FastClick-enabled links ignores any :hover state and goes straight to following the link.

This makes FastClick unusable for nav menus that use CSS :hover to show more content. My current solution is to use preventDefault() for any clicks on the top level of the nav, triggering their :hover but not following the link, but this makes the then-hovered item impossible to actually click through. While this is usable, I wondered if there could be a better solution.

The website I'm using is http://www.horizonindy.org/missions, if you'd like to see my workaround. The preventDefault() triggers a console log so you can see. (Website entirely unfinished)

I understand that some people are against using CSS hovering to display essential elements.
FastClick is amazing, thank you for taking the time to write it!

reinstantiating fastclick on document.body after dynamic content load causes doppelclick

instantiating "new FastClick(document.body)" works perfectly.

For DOM elements loaded after the fact, however, clicks are slow.

Calling "new FastClick(document.body)" after new elements are loaded (with or without a handler that we set to null) attaches a second listener to document body, so anything that's a toggle now receives two clicks, causing a hide/show.

The destroy method doesn't seem to work.

Fastclick doesn't work for iOS 4.3.3

Hi

I had to disable fastclick because visitors using iOS 4.3.3 were unable to reliably click on links, I've had this confirmed using an iPhone : sometimes clicks will work, sometimes they'll not.

I've seen FastClick.prototype.deviceIsIOS4, has anyone really managed to get clicks 100% working under iOS4 ?

laurent

Breaks form submit

Hitting enter on an input field no longer executes the form submit event after instantiating FastClick.

FastClick clicks on incorrect element if using iOS 6 and an active CSS transition or scroll fling

iOS 6 appears to have introduced a bug where the event.target element for input events is incorrect if the input was within an area that is being actively scrolled or CSS transformed. The event.target supplied by the browser isn't the element targeted by the input event; instead, it is the element that was at that position before the scroll/transition started.

This means that FastClick currently can click an element other than the intended element if it is within a parent that is being transitioned or is being scrolled.

(This is the underlying cause of Issue #42, although it may still be desirable not to send clicks when an element is scrolling.)

Further investigation seems to find that document.elementFromPoint can be used as a workaround as it gives the correct coordinates, but only reliably if it is called after event.targetElement, which seems to trigger an update of some kind after it's used. I've put a reduced testcase showing the odd behaviour up at http://beent.je/ios-targetelement-bug.html .

(Appears to still be present in iOS 6.1b4, so reported to Apple as rdar://13048589 )

Apple Webkit/533 17.9 and fastclick not getting along

Hi, just mentioning issues with this version of AppleWebkit in case someone is running into the same problem.(Apple Webkit 533 17.9 is the default version of Safari in in iOS 04.10.01)

The behaviour of FastClick is most strange, seems that it cannot resolve the tagName property. However, we tried the w3 DOM tests links and DOM support is fine on the browser.

Errors are reported on this line:
targetTagName = targetElement.tagName.toLowerCase();

But what it seems is really happening is that click events are thrown more than once. We were able to reproduce it somewhat reliably with the following code (as you can see couldn't be any simpler)

focus triggered on incorrect field after scroll.

Hi everyone,

We're using fastclick in an iOS web application, and are encountering an issue with focus and fastclick.

See the fiddle here:

http://jsfiddle.net/xJrsW/

open this URL in iOS: http://jsfiddle.net/xJrsW/embedded/result/

The problem occurs when the iPhone scrolls as a part of focusing the field.

  1. I scroll the to the very top of the document:
  2. I tap (and hold) on textfield 3, then release
  3. textfield 5 focuses

the problem is intermittent, and a simple quick tap on #3 does not cause the problem.

Any ideas on what might be going on?

Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.