From a8a09217f1784ee9a4f3900e532b924f51cd25ee Mon Sep 17 00:00:00 2001 From: Justin Vanderheide Date: Fri, 4 Apr 2014 14:47:25 -0400 Subject: [PATCH] fix(ngTouch): fix ghost click on small touch delta ngClick was leaking ghost click events when the touch Startmoved a small distance. This is because if there was a touchMove event between the touchStart and touchEnd preventGhostClick would not be called. This also caused the MOVE_TOLERANCE threshold to be ignored because any change in position would stop preventGhostClick from being run. Cancelling a tap is now correctly based on the MOVE_TOLERANCE, and ghost clicks are not leaked. Closes #6251 --- src/ngTouch/directive/ngClick.js | 5 +---- test/ngTouch/directive/ngClickSpec.js | 9 +++++---- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/ngTouch/directive/ngClick.js b/src/ngTouch/directive/ngClick.js index 7e558defc9f5..21a90f0cceeb 100644 --- a/src/ngTouch/directive/ngClick.js +++ b/src/ngTouch/directive/ngClick.js @@ -195,19 +195,16 @@ ngTouch.directive('ngClick', ['$parse', '$timeout', '$rootElement', // Actual linking function. return function(scope, element, attr) { var clickHandler = $parse(attr.ngClick), - tapping = false, tapElement, // Used to blur the element after a tap. startTime, // Used to check if the tap was held too long. touchStartX, touchStartY; function resetState() { - tapping = false; element.removeClass(ACTIVE_CLASS_NAME); } element.on('touchstart', function(event) { - tapping = true; tapElement = event.target ? event.target : event.srcElement; // IE uses srcElement. // Hack for Safari, which can target text nodes instead of containers. if(tapElement.nodeType == 3) { @@ -242,7 +239,7 @@ ngTouch.directive('ngClick', ['$parse', '$timeout', '$rootElement', var y = e.clientY; var dist = Math.sqrt( Math.pow(x - touchStartX, 2) + Math.pow(y - touchStartY, 2) ); - if (tapping && diff < TAP_DURATION && dist < MOVE_TOLERANCE) { + if (diff < TAP_DURATION && dist < MOVE_TOLERANCE) { // Call preventGhostClick so the clickbuster will catch the corresponding click. preventGhostClick(x, y); diff --git a/test/ngTouch/directive/ngClickSpec.js b/test/ngTouch/directive/ngClickSpec.js index 921c64578b2b..b984a5fd1b41 100644 --- a/test/ngTouch/directive/ngClickSpec.js +++ b/test/ngTouch/directive/ngClickSpec.js @@ -87,6 +87,7 @@ describe('ngClick (touch)', function() { x: 10, y: 10 }); + browserTrigger(element, 'touchmove'); browserTrigger(element, 'touchend',{ keys: [], x: 400, @@ -97,7 +98,7 @@ describe('ngClick (touch)', function() { })); - it('should not click if a touchmove comes before touchend', inject(function($rootScope, $compile, $rootElement) { + it('should click if the touchend is close', inject(function($rootScope, $compile, $rootElement) { element = $compile('
')($rootScope); $rootElement.append(element); $rootScope.$digest(); @@ -112,11 +113,11 @@ describe('ngClick (touch)', function() { browserTrigger(element, 'touchmove'); browserTrigger(element, 'touchend',{ keys: [], - x: 400, - y: 400 + x: 15, + y: 15 }); - expect($rootScope.tapped).toBeUndefined(); + expect($rootScope.tapped).toBe(true); })); it('should add the CSS class while the element is held down, and then remove it', inject(function($rootScope, $compile, $rootElement) {