Skip to content

Commit

Permalink
fix(tap): Normalize taps w/ pointer events also
Browse files Browse the repository at this point in the history
Some browsers already remove the delay with certain settings, such as
the CSS property `touch-events: none` or with specific meta tag
viewport values. However, each of these browsers still handle clicks
differently, such as when to fire off or cancel the event (like
scrolling when the target is a button, or holding a button down). For
browsers that already remove the 300ms delay, consider Ionic's tap
system as a way to normalize how clicks are handled across the various
devices so there's an expected response no matter what the device,
platform or version. Additionally, Ionic will prevent ghostclicks which
even browsers that remove the delay still experience.
  • Loading branch information
Adam Bradley committed May 12, 2014
1 parent ed3ee1d commit 1a2e501
Showing 1 changed file with 42 additions and 6 deletions.
48 changes: 42 additions & 6 deletions js/utils/tap.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,15 @@
* [fastclick](https://github.com/ftlabs/fastclick) and Angular's
* [ngTouch](https://docs.angularjs.org/api/ngTouch) should not be included, to avoid conflicts.
*
* Some browsers already remove the delay with certain settings, such as the CSS property
* `touch-events: none` or with specific meta tag viewport values. However, each of these
* browsers still handle clicks differently, such as when to fire off or cancel the event
* (like scrolling when the target is a button, or holding a button down).
* For browsers that already remove the 300ms delay, consider Ionic's tap system as a way to
* normalize how clicks are handled across the various devices so there's an expected response
* no matter what the device, platform or version. Additionally, Ionic will prevent
* ghostclicks which even browsers that remove the delay still experience.
*
* In some cases, third-party libraries may also be working with touch events which can interfere
* with the tap system. For example, mapping libraries like Google or Leaflet Maps often implement
* a touch detection system which conflicts with Ionic's tap system.
Expand Down Expand Up @@ -67,6 +76,7 @@ var tapPointerMoved;
var tapPointerStart;
var tapTouchFocusedInput;
var tapLastTouchTarget;
var tapTouchMoveListener = 'touchmove';

var TAP_RELEASE_TOLERANCE = 6; // how much the coordinates can be off between start/end, but still a click

Expand All @@ -82,6 +92,16 @@ var tapEventListeners = {
'touchcancel': tapTouchCancel,
'touchmove': tapTouchMove,

'pointerdown': tapTouchStart,
'pointerup': tapTouchEnd,
'pointercancel': tapTouchCancel,
'pointermove': tapTouchMove,

'MSPointerDown': tapTouchStart,
'MSPointerUp': tapTouchEnd,
'MSPointerCancel': tapTouchCancel,
'MSPointerMove': tapTouchMove,

'focusin': tapFocusIn,
'focusout': tapFocusOut
};
Expand All @@ -94,9 +114,25 @@ ionic.tap = {
tapEventListener('click', true, true);
tapEventListener('mouseup');
tapEventListener('mousedown');
tapEventListener('touchstart');
tapEventListener('touchend');
tapEventListener('touchcancel');

if( window.navigator.pointerEnabled ) {
tapEventListener('pointerdown');
tapEventListener('pointerup');
tapEventListener('pointcancel');
tapTouchMoveListener = 'pointermove';

} else if (window.navigator.msPointerEnabled) {
tapEventListener('MSPointerDown');
tapEventListener('MSPointerUp');
tapEventListener('MSPointerCancel');
tapTouchMoveListener = 'MSPointerMove';

} else {
tapEventListener('touchstart');
tapEventListener('touchend');
tapEventListener('touchcancel');
}

tapEventListener('focusin');
tapEventListener('focusout');

Expand Down Expand Up @@ -314,7 +350,7 @@ function tapTouchStart(e) {
tapEnableTouchEvents();
tapPointerStart = getPointerCoordinates(e);

tapEventListener('touchmove');
tapEventListener(tapTouchMoveListener);
ionic.activator.start(e);

if( ionic.Platform.isIOS() && ionic.tap.isLabelWithTextInput(e.target) ) {
Expand Down Expand Up @@ -350,14 +386,14 @@ function tapTouchEnd(e) {
function tapTouchMove(e) {
if( tapHasPointerMoved(e) ) {
tapPointerMoved = true;
tapEventListener('touchmove', false);
tapEventListener(tapTouchMoveListener, false);
ionic.activator.end();
return false;
}
}

function tapTouchCancel(e) {
tapEventListener('touchmove', false);
tapEventListener(tapTouchMoveListener, false);
ionic.activator.end();
tapPointerMoved = false;
}
Expand Down

0 comments on commit 1a2e501

Please sign in to comment.