Unified · Split
| @@ -1,7 +1,7 @@ | |||
| 1 | /** | 1 | /** |
| 2 | * @preserve FastClick: polyfill to remove click delays on browsers with touch UIs. | 2 | * @preserve FastClick: polyfill to remove click delays on browsers with touch UIs. |
| 3 | * | 3 | * |
| 4 | * @version 1.0.0 | 4 | * @version 1.0.1 |
| 5 | * @codingstandard ftlabs-jsv2 | 5 | * @codingstandard ftlabs-jsv2 |
| 6 | * @copyright The Financial Times Limited [All Rights Reserved] | 6 | * @copyright The Financial Times Limited [All Rights Reserved] |
| 7 | * @license MIT License (see LICENSE.txt) | 7 | * @license MIT License (see LICENSE.txt) |
| @@ -16,11 +16,13 @@ · 8 unmodified lines | |||
| 16 | * | 16 | * |
| 17 | * @constructor | 17 | * @constructor |
| 18 | * @param {Element} layer The layer to listen on | 18 | * @param {Element} layer The layer to listen on |
| 19 | * @param {Object} options The options to override the defaults | ||
| 19 | */ | 20 | */ |
| 20 | function FastClick(layer) { | 21 | function FastClick(layer, options) { |
| 21 | 'use strict'; | 22 | 'use strict'; |
| 22 | var oldOnClick; | 23 | var oldOnClick; |
| 23 | 24 | ||
| 25 | options = options || {}; | ||
| 24 | 26 | ||
| 25 | /** | 27 | /** |
| 26 | * Whether a click is currently being tracked. | 28 | * Whether a click is currently being tracked. |
| @@ -31,7 +33,7 @@ function FastClick(layer) { · 4 unmodified lines | |||
| 31 | 33 | ||
| 32 | 34 | ||
| 33 | /** | 35 | /** |
| 34 | * Timestamp for when when click tracking started. | 36 | * Timestamp for when click tracking started. |
| 35 | * | 37 | * |
| 36 | * @type number | 38 | * @type number |
| 37 | */ | 39 | */ |
| @@ -75,7 +77,7 @@ function FastClick(layer) { · 37 unmodified lines | |||
| 75 | * | 77 | * |
| 76 | * @type number | 78 | * @type number |
| 77 | */ | 79 | */ |
| 78 | this.touchBoundary = 10; | 80 | this.touchBoundary = options.touchBoundary || 10; |
| 79 | 81 | ||
| 80 | 82 | ||
| 81 | /** | 83 | /** |
| @@ -85,6 +87,13 @@ function FastClick(layer) { · 3 unmodified lines | |||
| 85 | */ | 87 | */ |
| 86 | this.layer = layer; | 88 | this.layer = layer; |
| 87 | 89 | ||
| 90 | /** | ||
| 91 | * The minimum time between tap(touchstart and touchend) events | ||
| 92 | * | ||
| 93 | * @type number | ||
| 94 | */ | ||
| 95 | this.tapDelay = options.tapDelay || 200; | ||
| 96 | |||
| 88 | if (FastClick.notNeeded(layer)) { | 97 | if (FastClick.notNeeded(layer)) { |
| 89 | return; | 98 | return; |
| 90 | } | 99 | } |
| @@ -94,18 +103,25 @@ function FastClick(layer) { · 3 unmodified lines | |||
| 94 | return function() { return method.apply(context, arguments); }; | 103 | return function() { return method.apply(context, arguments); }; |
| 95 | } | 104 | } |
| 96 | 105 | ||
| 106 | |||
| 107 | var methods = ['onMouse', 'onClick', 'onTouchStart', 'onTouchMove', 'onTouchEnd', 'onTouchCancel']; | ||
| 108 | var context = this; | ||
| 109 | for (var i = 0, l = methods.length; i < l; i++) { | ||
| 110 | context[methods[i]] = bind(context[methods[i]], context); | ||
| 111 | } | ||
| 112 | |||
| 97 | // Set up event handlers as required | 113 | // Set up event handlers as required |
| 98 | if (deviceIsAndroid) { | 114 | if (deviceIsAndroid) { |
| 99 | layer.addEventListener('mouseover', bind(this.onMouse, this), true); | 115 | layer.addEventListener('mouseover', this.onMouse, true); |
| 100 | layer.addEventListener('mousedown', bind(this.onMouse, this), true); | 116 | layer.addEventListener('mousedown', this.onMouse, true); |
| 101 | layer.addEventListener('mouseup', bind(this.onMouse, this), true); | 117 | layer.addEventListener('mouseup', this.onMouse, true); |
| 102 | } | 118 | } |
| 103 | 119 | ||
| 104 | layer.addEventListener('click', bind(this.onClick, this), true); | 120 | layer.addEventListener('click', this.onClick, true); |
| 105 | layer.addEventListener('touchstart', bind(this.onTouchStart, this), false); | 121 | layer.addEventListener('touchstart', this.onTouchStart, false); |
| 106 | layer.addEventListener('touchmove', bind(this.onTouchMove, this), false); | 122 | layer.addEventListener('touchmove', this.onTouchMove, false); |
| 107 | layer.addEventListener('touchend', bind(this.onTouchEnd, this), false); | 123 | layer.addEventListener('touchend', this.onTouchEnd, false); |
| 108 | layer.addEventListener('touchcancel', bind(this.onTouchCancel, this), false); | 124 | layer.addEventListener('touchcancel', this.onTouchCancel, false); |
| 109 | 125 | ||
| 110 | // Hack is required for browsers that don't support Event#stopImmediatePropagation (e.g. Android 2) | 126 | // Hack is required for browsers that don't support Event#stopImmediatePropagation (e.g. Android 2) |
| 111 | // which is how FastClick normally stops click events bubbling to callbacks registered on the FastClick | 127 | // which is how FastClick normally stops click events bubbling to callbacks registered on the FastClick |
| @@ -410,7 +426,7 @@ FastClick.prototype.onTouchStart = function(event) { · 298 unmodified lines | |||
| 410 | this.touchStartY = touch.pageY; | 426 | this.touchStartY = touch.pageY; |
| 411 | 427 | ||
| 412 | // Prevent phantom clicks on fast double-tap (issue #36) | 428 | // Prevent phantom clicks on fast double-tap (issue #36) |
| 413 | if ((event.timeStamp - this.lastClickTime) < 200) { | 429 | if ((event.timeStamp - this.lastClickTime) < this.tapDelay) { |
| 414 | event.preventDefault(); | 430 | event.preventDefault(); |
| 415 | } | 431 | } |
| 416 | 432 | ||
| @@ -498,7 +514,7 @@ FastClick.prototype.onTouchEnd = function(event) { · 81 unmodified lines | |||
| 498 | } | 514 | } |
| 499 | 515 | ||
| 500 | // Prevent phantom clicks on fast double-tap (issue #36) | 516 | // Prevent phantom clicks on fast double-tap (issue #36) |
| 501 | if ((event.timeStamp - this.lastClickTime) < 200) { | 517 | if ((event.timeStamp - this.lastClickTime) < this.tapDelay) { |
| 502 | this.cancelNextClick = true; | 518 | this.cancelNextClick = true; |
| 503 | return true; | 519 | return true; |
| 504 | } | 520 | } |
| @@ -548,7 +564,8 @@ FastClick.prototype.onTouchEnd = function(event) { · 43 unmodified lines | |||
| 548 | this.sendClick(targetElement, event); | 564 | this.sendClick(targetElement, event); |
| 549 | 565 | ||
| 550 | // Select elements need the event to go through on iOS 4, otherwise the selector menu won't open. | 566 | // Select elements need the event to go through on iOS 4, otherwise the selector menu won't open. |
| 551 | if (!deviceIsIOS4 || targetTagName !== 'select') { | 567 | // Also this breaks opening selects when VoiceOver is active on iOS6, iOS7 (and possibly others) |
| 568 | if (!deviceIsIOS || targetTagName !== 'select') { | ||
| 552 | this.targetElement = null; | 569 | this.targetElement = null; |
| 553 | event.preventDefault(); | 570 | event.preventDefault(); |
| 554 | } | 571 | } |
| @@ -750,10 +767,11 @@ FastClick.notNeeded = function(layer) { · 195 unmodified lines | |||
| 750 | * Factory method for creating a FastClick object | 767 | * Factory method for creating a FastClick object |
| 751 | * | 768 | * |
| 752 | * @param {Element} layer The layer to listen on | 769 | * @param {Element} layer The layer to listen on |
| 770 | * @param {Object} options The options to override the defaults | ||
| 753 | */ | 771 | */ |
| 754 | FastClick.attach = function(layer) { | 772 | FastClick.attach = function(layer, options) { |
| 755 | 'use strict'; | 773 | 'use strict'; |
| 756 | return new FastClick(layer); | 774 | return new FastClick(layer, options); |
| 757 | }; | 775 | }; |
| 758 | 776 | ||
| 759 | 777 | ||