Skip to content
This repository was archived by the owner on Jun 9, 2022. It is now read-only.
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 35 additions & 8 deletions lib/fastclick.js
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,21 @@
// Issue #160: on iOS 7, some input elements (e.g. date datetime month) throw a vague TypeError on setSelectionRange. These elements don't have an integer value for the selectionStart and selectionEnd properties, but unfortunately that can't be used for detection because accessing the properties also throws a TypeError. Just check the type instead. Filed as Apple bug #15122724.
if (deviceIsIOS && targetElement.setSelectionRange && targetElement.type.indexOf('date') !== 0 && targetElement.type !== 'time' && targetElement.type !== 'month' && targetElement.type !== 'email') {
length = targetElement.value.length;

// Calling focus() here fixes this:
// https://github.com/ftlabs/fastclick/issues/548
//
// No idea why this works, but calling focus() fixes at least this scenario:
// - iOS 11.3
// - Cordova with UIWebView
// - Open page with datetime input and text input
// - Tap datetime input, close the popup
// - Quickly tap text input
// -> Nothing happens (this is fixed by calling focus())
// - Tap text input for a longer time
// -> Text input is focused
targetElement.focus();

targetElement.setSelectionRange(length, length);
} else {
targetElement.focus();
Expand Down Expand Up @@ -389,7 +404,13 @@
* @returns {boolean}
*/
FastClick.prototype.onTouchStart = function(event) {
var targetElement, touch, selection;
var targetElement, touch, selection, touchStartTime;

// iOS (at least 11.4 and 11.4 beta) can return smaller event.timeStamp values after resuming with
// Cordova using UIWebView (and possibly also with mobile Safari?), the timeStamp values can also
// be negative
// https://github.com/ftlabs/fastclick/issues/549
touchStartTime = (new Date()).getTime();

// Ignore multiple touches, otherwise pinch-to-zoom is prevented if both fingers are on the FastClick element (issue #111).
if (event.targetTouches.length > 1) {
Expand Down Expand Up @@ -435,14 +456,14 @@
}

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

this.touchStartX = touch.pageX;
this.touchStartY = touch.pageY;

// Prevent phantom clicks on fast double-tap (issue #36)
if ((event.timeStamp - this.lastClickTime) < this.tapDelay) {
if ((touchStartTime - this.lastClickTime) < this.tapDelay) {
event.preventDefault();
}

Expand Down Expand Up @@ -519,26 +540,32 @@
* @returns {boolean}
*/
FastClick.prototype.onTouchEnd = function(event) {
var forElement, trackingClickStart, targetTagName, scrollParent, touch, targetElement = this.targetElement;
var forElement, trackingClickStart, targetTagName, scrollParent, touch, touchEndTime, targetElement = this.targetElement;

// iOS (at least 11.4 and 11.4 beta) can return smaller event.timeStamp values after resuming with
// Cordova using UIWebView (and possibly also with mobile Safari?), the timeStamp values can also
// be negative
// https://github.com/ftlabs/fastclick/issues/549
touchEndTime = (new Date()).getTime();

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

// Prevent phantom clicks on fast double-tap (issue #36)
if ((event.timeStamp - this.lastClickTime) < this.tapDelay) {
if ((touchEndTime - this.lastClickTime) < this.tapDelay) {
this.cancelNextClick = true;
return true;
}

if ((event.timeStamp - this.trackingClickStart) > this.tapTimeout) {
if ((touchEndTime - this.trackingClickStart) > this.tapTimeout) {
return true;
}

// Reset to prevent wrong click cancel on input (issue #156).
this.cancelNextClick = false;

this.lastClickTime = event.timeStamp;
this.lastClickTime = touchEndTime;

trackingClickStart = this.trackingClickStart;
this.trackingClick = false;
Expand Down Expand Up @@ -571,7 +598,7 @@

// Case 1: If the touch started a while ago (best guess is 100ms 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.
// Case 2: Without this exception for input elements tapped when the document is contained in an iframe, then any inputted text won't be visible even though the value attribute is updated as the user types (issue #37).
if ((event.timeStamp - trackingClickStart) > 100 || (deviceIsIOS && window.top !== window && targetTagName === 'input')) {
if ((touchEndTime - trackingClickStart) > 100 || (deviceIsIOS && window.top !== window && targetTagName === 'input')) {
this.targetElement = null;
return false;
}
Expand Down