Skip to content
Permalink
Browse files

Add fix for issue #36. The solution isn't ideal and requires a nasty …

…workaround where we guess whether a click event is going to be fired if the touch started more than 150ms ago.
  • Loading branch information...
mattcg committed Nov 30, 2012
1 parent dc59439 commit 566a140133617fbdab7d2dede7f93652710425e6
Showing with 31 additions and 10 deletions.
  1. +1 −1 component.json
  2. +23 −2 lib/fastclick.js
  3. +1 −1 package.json
  4. +6 −6 tests/36.html
@@ -1,7 +1,7 @@
{
"name": "fastclick",
"description": "Polyfill to remove click delays on browsers with touch UIs.",
"version": "0.4.2",
"version": "0.4.3",
"main": "lib/fastclick.js",
"scripts": [
"lib/fastclick.js"
@@ -1,7 +1,7 @@
/**
* @preserve FastClick: polyfill to remove click delays on browsers with touch UIs.
*
* @version 0.4.2
* @version 0.4.3
* @codingstandard ftlabs-jslint
* @copyright The Financial Times Limited [All Rights Reserved]
* @license MIT License (see LICENSE.txt)
@@ -30,6 +30,14 @@ function FastClick(layer) {
this.trackingClick = false;


/**
* Timestamp for when when click tracking started.
*
* @type number
*/
this.trackingClickStart = 0;


/**
* The element being tracked for a click.
*
@@ -183,6 +191,7 @@ FastClick.prototype.onTouchStart = function(event) {
var touch = event.targetTouches[0];

this.trackingClick = true;
this.trackingClickStart = event.timeStamp;
this.targetElement = event.target;

this.touchStartX = touch.pageX;
@@ -265,13 +274,15 @@ FastClick.prototype.findControl = function(labelElement) {
*/
FastClick.prototype.onTouchEnd = function(event) {
'use strict';
var forElement, targetElement = this.targetElement;
var forElement, trackingClickStart, targetElement = this.targetElement;

if (!this.trackingClick) {
return true;
}

trackingClickStart = this.trackingClickStart;
this.trackingClick = false;
this.trackingClickStart = 0;

if (targetElement.nodeName.toLowerCase() === 'label') {
forElement = this.findControl(targetElement);
@@ -288,10 +299,20 @@ FastClick.prototype.onTouchEnd = function(event) {
return false;
}
} else if (this.needsFocus(targetElement)) {

// If the touch started a while ago (best guess is 150ms based on tests for issue #36) then focus will be triggered anyway. Return early and unset the target element reference so that the subsequent click will be allowed through.
if ((event.timeStamp - trackingClickStart) > 150) {
this.targetElement = null;
return true;
}

targetElement.focus();

// Select elements need the event to go through at least on iOS, otherwise the selector menu won't open.
if (targetElement.tagName.toLowerCase() !== 'select') {
event.preventDefault();
}

return false;
}

@@ -1,6 +1,6 @@
{
"name": "fastclick",
"version": "0.4.2",
"version": "0.4.3",
"author": "FT Labs <enquiries@labs.ft.com> (http://labs.ft.com/)",
"description": "Polyfill to remove click delays on browsers with touch UIs.",
"contributors": [
@@ -14,18 +14,18 @@
<script type="application/javascript">
window.addEventListener('load', function() {
new FastClick(document.body);
}, false)
}, false);
</script>
</head>
<body>
<p>A tap and long hold, then release on input #1 will sometimes trigger focus on #2.</p>
<hr />
<form>
<p><input placeholder="1" /></p>
<p><input placeholder="2" /></p>
<p><input placeholder="3" /></p>
<p><input placeholder="4" /></p>
<p><input placeholder="5" /></p>
<p><input placeholder="1" name="i1" /></p>
<p><input placeholder="2" name="i2" /></p>
<p><input placeholder="3" name="i3" /></p>
<p><input placeholder="4" name="i4" /></p>
<p><input placeholder="5" name="i5" /></p>
</form>
</body>
</html>

0 comments on commit 566a140

Please sign in to comment.
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.