ngTouch 1.2.1 on Safari iOS 7 fires a second time by tapping wherever on the screen:
I am also having hard times with this issue.
Any ideas what's causing this, and if there's a workaround that I could use?
I think it's something related to the event propagation, this is my workaround:
I have a similar problem.
My app has a popup dialog with a button that closes it. When the dialog's button is on top of a text input element, clicking the button on touch screen devices not only closes the dialog, but also focuses the input.
Same problem here using angular w/ angular-touch 1.2.9.
There is no other clickable elements in the tree to propagate to. The _very same_ click event is fired twice in a row. This does not happen with the swipes. Also, the problem of firing ngClick events twice disappears when I remove ngTouch from the project.
I am also having this problem in ngTouch 1.2.13,
Depending on the situation, this is more than an optical bug, but in my case leads to rather annoying usability problems:
For example I change a View with activated ngTouch and with ng-click on a touch device for to open a modal, which lays it self above the clicked element. Within this modal a clickable element is at the same place as the previously clicked element (now laying above), then it could occur that the second event is fired and the button in modal is clicked/fired.
This could lead to unwanted behaviour of the application.
Hi Richard, this is exactly same same kind of problem we are facing.
Reference jquery (before angular.js) to stop the event propagation and prevent the double fires.
That doesn't sound like a fix. We do not use jQuery in our application. Is this string saying that this will not be addressed prior to 1.3?
This issue is making ngClick
unusable. How are people working around this? Debounce? Fallback to original ngClick?
I added ngTouch
to get swipe functionality, and now I'm saddled with this issue.
We've been running our own fork of ng-touch with the changes in https://github.com/angular/angular.js/pull/6995
Other than that, I've seen projects doing manual debouncing where clicks within ~200ms of each other are disregarded.
I'm running into this issue too. @coma's workaround seems to have fixed it.
just started using angular-material and ran into this issue since material includes aria.
+1 using material as well having the same issue.
any updates for this issue? and is there a workaround? I am using ngtouch 1.3.14 and still having this issue
+1
Any update on this issue? Developing an app using angular-material and it works great on desktop but on mobile ng-click registers twice.
In my case jquery (as a dependency of ui-calendar) caused this problem. couldn´t find a fix...
+1
+1
With above 2 commits, added some sort of debounce effect.. The threshold amount set fixes my ngTouch firing twice issues, please test and see if it also worked in your case..
On GenyMotion on an Android 4.1 emulator I always get event.timeStamp undefined => no bounce occurs.
@mobilabgit Are you suggesting manually creating event timeStamps via new Date()
is more environment proof than event.timeStamp
.. ??
not suggesting anything, just stating the fact that in the stated configuration the event.timeStamp returns undefined.
Any update on this? This is causing havok in my application. Menus and buttons are firing clicks twice.
I am suffering from this problem as well. button's fire ng-click twice.. make the application's data input almost unusable on ios, very frustrating indeed.
@mobilabgit @jgodi @rexebin Are you guys using Angular Material by any chance??
@NorikDavtian yes, and the good news is that they solved the issue on their master branch.. you can check these resources for more info on the issue
https://github.com/angular/angular.js/pull/10766
and this codepen demonstrates the different versions... you can try to combine them to know what is working
http://codepen.io/marcysutton/pen/YPxrLd
for example ngMaterial 0.7.1 with ngAria < 2.1.5 doesn't have the bug...
waiting for ngMaterial > 0.8.3 ( currently on master ) which have fixed the bug also
I have solved the problem by removing material design 0.83.Â
I also removed bootstrap.js and in its place using bootstrap ui jus only. Â as a result reversing back to angular a 1.2.28. Just in case bootstrap ui does not work somewhere with 1.3.x. Unknown bugs are scary.
I hated the bug so much that I also removed ng-touch too.
Now I do have 300ms delay on clicks, but it feels solid stable, I rate stable over the performance panaty by the delay.
The iOS Safari sub debug is not the best debug experice I am afraid. The bug costs me 3 days of work. Forced me to refactor me code, changing all material design element to the good old bootstrap setup. Beta is indeed not intended for production use.
Hope the above saved someone some time.
—
Sent from Mailbox
On Fri, Mar 27, 2015 at 1:13 AM, Ahmed Abdel Razzak
[email protected] wrote:
@NorikDavtian yes, and the good news is that they solved the issue on their master branch.. you can check these resources for more info on the issue
https://github.com/angular/angular.js/pull/10766
and this codepen demonstrates the different versions... you can try to combine them to know what is working
http://codepen.io/marcysutton/pen/YPxrLd
for example the master branch on ngMaterial fine works
and ngMaterial 0.7 with ngAria < 2.1.5 doesn't have the bug...waiting for ngMaterial > 8.3 ( currently on master ) which have fixed the bug also
Reply to this email directly or view it on GitHub:
https://github.com/angular/angular.js/issues/6251#issuecomment-86781164
Thanks @artmees .. Solving root cause of the problem was a better solution than adding extra checks in ng touch
.. Everything working now.
Thanks @rexebin for the response.. I can totally relate, but we are not in production phase, so can tolerate few bugs here and there. But starting to be more selective with app dependency updates from this point on.
I'm new to angular and ran into this issue today. I just pulled via bower angular-touch. So I have the latest and it's not fixed there. Norik, can you clarify what I must do in order to get this working natively?
@dangros It's not the Angular Touch.. as @artmees mentioned it's the Angular Material library more specifically accessibility parts related to Aria..
Change your bower angular-material
to
"angular-material": "master"
or if you want to make sure your build will not break change it to current masters latest commit version.. Make sure to change to a stable release when the fix is merged into a new tag, else you will always be using master, which might cause other problems down the line..
Good luck.
I'm not using angular-material. Only angular-touch
Make these changes to your ng-touch
file.. your bower version might look slightly different but the content of it should look the same.
https://github.com/NorikDavtian/angular.js/blob/master/src/ngTouch/directive/ngClick.js
Let me know if it works..
If your problem persist I would be glad to do a screen session to diagnose your problem.
Thanks @NorikDavtian. I loved Material Design for its grid layout system, directives, services and ease of use and its design philosophy. I also loved the idea to get rid of the 300ms delay. I will have a play with a new project again and see how it goes, but not with my main project as it has a strict timeline.
Please correct me if I am wrong: the 300ms delay will exist wether we use ng-touch or material design or not. ng-touch and material design will send click straight away and hijack and stop the send click send by the browser. By making amendment to ngClick.js in ng-touch or pull the master branch of material design with ngclick fixes, I suppose it also hijack the normal hyper links so the hyper links do not double click.
@rexebin try using https://github.com/ftlabs/fastclick to remove the 300ms delay if opting out of the ng-touch, want it or not want it if you want a super fast click you have to alter the native browser behavior, otherwise you are stuck with that delay.
I tried fastclick. By using it, all ng-clicks will have to have special class on it to work properly. Otherwise it might click twice instantly and then two more 300ms later hopefully stopped by fastclick and ng-touch etc.
Sounds crazy. Is worth to go all the trouble to stop the 300ms by design on touch screens? I guess that depends..
—
Sent from Mailbox
On Sat, Mar 28, 2015 at 10:19 AM, Norik Davtian [email protected]
wrote:
@rexebin try using https://github.com/ftlabs/fastclick to remove the 300ms delay if opting out of the ng-touch, want it or not want it if you want a super fast click you have to alter the native browser behavior, otherwise you are stuck with that delay.
Reply to this email directly or view it on GitHub:
https://github.com/angular/angular.js/issues/6251#issuecomment-87200661
Hi all, this issue predates ngAria and Angular Material. There were ng-click
issues with ngAria in the past, but they should be fixed now. Angular Material is being updated to pull in angular-aria version 1.3.15, so that specific bug will go away. But considering this issue was opened in February 2014, any issues you may have had with Angular Material are unrelated.
This bug is also causing alot of havock in my application and I really don't want to resort to custom my-click directive for the most basic thing. I'm not using Angular Material libs.. only ng-touch. And I've just upgraded everything to angular 1.4 angular-touch 1.4 and very sad to see this bug affecting so many wasn't fixed in a milestone release :(
I'm also affected by the same issue:
bower deps:
"dependencies": {
"angular-animate": "1.3.16",
"angular-cookies": "1.3.16",
"angular-touch": "1.3.16",
"angular-sanitize": "1.3.16",
"jquery": "2.1.4",
"angular-resource": "1.3.16",
"angular-ui-router": "0.2.15",
"angular-material": "0.8.3",
"angular": "1.3.16",
"angular-leaflet-directive": "0.8.2",
"angular-moment": "0.10.1",
"ngDialog": "0.4.0",
"angular-strap": "2.2.4",
"bootstrap": "3.3.4",
"angular-carousel": "0.3.10",
"lodash": "3.9.3",
"angular-validation-match": "1.5.0",
"ng-file-upload": "5.0.1",
"angular-sweetalert": "1.1.0",
"Leaflet.awesome-markers": "2.0.2",
"angulartics": "0.18.0"
},
"devDependencies": {
"angular-mocks": "1.3.16"
},
"resolutions": {
"angular": "~1.3.x"
}
Just ran into this myself and im hating it, hope this will be fixed soon.
My quick fix is to make ng-click
use a scoped function and make that do a double click check like this:
doubleClickCheck = false
$scope.toggleShowPct = ->
if !doubleClickCheck
$scope.showPct = !$scope.showPct
doubleClickCheck = true
$timeout ->
doubleClickCheck = false
, 100
@coma Thanks for your working workaround. I am using this with menu items that use the attribute directive "menu-close". How can I maintain that functionality with your workaround?
Hey @jbeuckm! I don't know that directive, is something coming from some bootstrap/material/fancy library?
Ah yes I guess it does come from a fancy library: Ionic. Here is the directive:
https://github.com/driftyco/ionic/blob/master/js/angular/directive/menuClose.js#L1
I too had this issue where any time I called a scope function, it was fired twice, and although you can do a workaround like @tcarlsen suggested, having to do this for every function call would be pretty tedious, unnecessary and slow.
Fortunately, I found out angular-material had a click Hijack method, and you are able to turn that off.
To disable angular-mateiral click hijack, you just need to put this into your config file:
.config(function( $mdGestureProvider ) {
$mdGestureProvider.skipClickHijack();
});
I've been testing this solution and it seems to resolve the issue. However, I've only tried it with ng-click. I'm not sure how it will affect any other angular-material gestures, but for now, my functions are only being called once :)
Same issue here too.
I have a
I've tried lots of work arounds but having no luck. It's a blocker on a particular section of the application I'm currently developing :(
@DaDanny thanks a lot! I tried what you say ,and it works !!
After enabling this plugin I have the problem on Android (tested on 4.2.2 and 4.4.4) When I click on button layout changes there is another click event fired which directs me to another location. When I removed the plugin app works as supposed to.
@sterichards and @Grzegorzsa : Have you guys tried my solution I posted above?
If you have and the function is still firing twice, make sure you don't have both
<ion-view ng-controller="MyCtrl">
</ion-view>
and something like
.state('mystate', {
url: '/myState',
templateUrl: 'routes/myview.html',
controller: 'MyCtrl'
})
This will load the controller twice which would also cause this issue.
I'd first make sure thats not the case, then implement my solution above.
Cheers and let me know if that helps :)
I made some changes to ngTouch and it works for my mobile project.
I think there is some bugs on ngTouch module.
Basically ngTouch tries to trigger click event with touch-end event, and bypass click event.
But on touch device on touch event, it fails first x,y position check.
Additionally, if out touch > move > end and tap again on first touch position, you get click twice!
This happens when you touch again in PREVENT_DURATION time(default 2500 ms).
So I added touchmove event to reset this on touch move.
Anyway, hope this help somebody needs.
diff --git a/src/ngTouch/directive/ngClick.js b/src/ngTouch/directive/ngClick.js
index f352c25..ba74248 100644
--- a/src/ngTouch/directive/ngClick.js
+++ b/src/ngTouch/directive/ngClick.js
@@ -126,13 +126,14 @@ ngTouch.directive('ngClick', ['$parse', '$timeout', '$rootElement',
}
var touches = event.touches && event.touches.length ? event.touches : [event];
+ var realTouch = touches != [event]; // check this is a real touch event
var x = touches[0].clientX;
var y = touches[0].clientY;
// Work around desktop Webkit quirk where clicking a label will fire two clicks (on the label
// and on the input element). Depending on the exact browser, this second click we don't want
// to bust has either (0,0), negative coordinates, or coordinates equal to triggering label
// click event
- if (x < 1 && y < 1) {
+ if (!realTouch && x < 1 && y < 1) {
return; // offscreen
}
if (lastLabelClickCoordinates &&
@@ -183,12 +184,18 @@ ngTouch.directive('ngClick', ['$parse', '$timeout', '$rootElement',
}, PREVENT_DURATION, false);
}
+ // Global touchmove hander that removes touchcoordinates while moving
+ function onTouchMove(event) {
+ touchCoordinates = []; //reset touch zone
+ }
+
// On the first call, attaches some event handlers. Then whenever it gets called, it creates a
// zone around the touchstart where clicks will get busted.
function preventGhostClick(x, y) {
if (!touchCoordinates) {
$rootElement[0].addEventListener('click', onClick, true);
$rootElement[0].addEventListener('touchstart', onTouchStart, true);
+ $rootElement[0].addEventListener('touchmove', onTouchMove, true);
touchCoordinates = [];
}
@wormkid - I am having trouble identifying the problem here. Is it possible that you could create a unit test to demonstrate this issue?
@petebacondarwin - You can test or download http://zen-dev.pl/angular-test.html
If you click on gray text it disappears, link below takes its place and gets triggered.
Link is outside of angular view. When the link is inside the view everything works fine.
@petebacondarwin - I made jsfiddle.
https://jsfiddle.net/rfz23qgm/5/
I can't reproduce "click twice on tap" on that fiddle, but can reproduce "click twice after scroll".
I'm testing with iPhone Safari.
You should do this step5 in 2.5 seconds.
It usually happens when reading some boards lists.
"press - move - release - tap the article under yout thumb"
Momentum scroll makes this between different articles (when release position is same as new tap position)
I had a similar issue using Angular Material's Bottom Sheet. For some reason, duplicate touchstart
events were happening at the same coordinates. This added duplicate entries to the touchCoordinates
array within ngClick
, and that allowed my Chrome desktop browser's "ghost" clicks. I stopped this issue with this change to the ngClick
directive's onTouchStart
method:
@@ -172,6 +172,13 @@
var y = touches[0].clientY;
touchCoordinates.push(x, y);
+ // Test if these coordinates are already allowed. Don't stack!
+ for (var i = 0; i < touchCoordinates.length; i += 2) {
+ if (touchCoordinates[i] == x && touchCoordinates[i + 1] == y) {
+ return;
+ }
+ }
+
$timeout(function() {
// Remove the allowable region.
for (var i = 0; i < touchCoordinates.length; i += 2) {
Since @DaDanny 's solution did not work for me, here is another workaround:
function onMyClick (e) {
if (e.type !== 'click') {
return;
}
// your stuff
}
This is a major pain in the ass because a click on an md-menu then focuses an input that was underneath it. It's driving me nuts, are we going to have a resolution soon?
Currently trying to use ngTouch in complement to the ui-bootstrap carousel.
As soon as I add ngTouch to the project I get this double click issue that make all controls such as inputs or selects unusable.
Is there any work in progress that fixes this issue?
The plan is to remove ngClick from ngTouch and recommend using fastclick.js instead.
Any comments?
Hum, fastclick creates other issues.
As an example, ng-places-autocomplete stops working properly as soon as fastclick.js is added to the project.
I wonder if that is a bug that could be fixed in ng-places-autocomplete?
No doubt it can be fixed in ng-places-autocomplete.
But, if we find one issue there, we'll probably find the same thing in other ui libs.
Just encountered this issue. Can confirm it is with ngTouch, as removing it caused the issue to disappear.
In my case, ng-click would eventually cause partials to be hidden and shown, with the input on the new partial that is in the same location as the ng-click triggering the keyboard.
Tried @NorikDavtian 's suggested fix as well as the code here (https://github.com/angular/angular.js/pull/11342) to no avail.
In my case, the fix came by adding $event.preventDefault() to the ng-click on the button where the event was originating.
Same issue, but fixed with the solution provided by @michaelyuen
<a data-ng-click="goTo($event, 'route/path')">Link</a>
$scope.goTo = function ($event, route) {
$event.preventDefault();
$location.url(route);
};
This bug was happening to me too. I try update ng-touch to 1.4.8, the last workaround but not works.
This was happen in a small dropdown window I fixed whit this.
scope.domFn = function($event, value) {
// hack to fix bug with angular ngTouch
if($event.type == "touchend") {return}
someAwsomeStuff(value);
};
I hope this help someone.
@Narretz From where can i get the latest ngTouch library file with ngClickOverride fix?
The change is in 1.5.0-rc.2. So it's not in any 1.4 branch. That's because it's not a bug fix, we simply decided to disable the ngClick.override directive. You should be able to use ngTouch .5 with 1.4 though
Most helpful comment
I too had this issue where any time I called a scope function, it was fired twice, and although you can do a workaround like @tcarlsen suggested, having to do this for every function call would be pretty tedious, unnecessary and slow.
Fortunately, I found out angular-material had a click Hijack method, and you are able to turn that off.
To disable angular-mateiral click hijack, you just need to put this into your config file:
I've been testing this solution and it seems to resolve the issue. However, I've only tried it with ng-click. I'm not sure how it will affect any other angular-material gestures, but for now, my functions are only being called once :)