Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS Click on TouchStart

Angular Touch ngTouch causes the click to occur on touch release.

Is there a way to make the click happen on touch start?

The fast-click directive below seems to do what I want on touchscreens, but it doesn't work with mouse clicks.

myApp.directive('fastClick', ['$parse', function ($parse) {
    return function (scope, element, attr) {
      var fn = $parse(attr['fastClick']);
      var initX, initY, endX, endY;
      var elem = element;

      elem.bind('touchstart', function (event) {
          event.preventDefault();
          initX = endX = event.touches[0].clientX;
          initY = endY = event.touches[0].clientY;
          scope.$apply(function () { fn(scope, { $event: event }); });
      });
    };
  }
]);
like image 329
benshope Avatar asked Jul 14 '14 20:07

benshope


2 Answers

Add click to the touchstart event - event.preventDefault() will cancel the event from happening twice:

elem.bind('touchstart click', function (event) {

A quick fastclick code that I use in one app is:

app.directive("ngMobileClick", [function () {
    return function (scope, elem, attrs) {
        elem.bind("touchstart click", function (e) {
            e.preventDefault();
            e.stopPropagation();

            scope.$apply(attrs["ngMobileClick"]);
        });
    }
}])

And use like: ng-mobile-click="myScopeFunction()"

like image 66
tymeJV Avatar answered Oct 02 '22 01:10

tymeJV


The answer of tymeJV is correct but when I've tried to overwrite ngClick directive the behaviour conflicted with ngTouch module - some clicks started firing twice. The reason is simple, ngTouch cares about the stuff but unfortunately has a bug.

In touchstart event handler instead of:

  var touches = event.touches && event.touches.length ? event.touches : [event];

it should have something like this:

var touches = null;
  if (event.touches && event.touches.length) {
      //AC: this is original library case
      touches = event.touches;
  } else if (event.originalEvent && event.originalEvent.touches && event.originalEvent.touches.length) {
      //AC: this is fix actually working
      touches =  event.originalEvent.touches;
  }else{
    touches = [event];
  }

i.e. event's touches field is undefined for some reason, but event.originalEvent.touches is fine.

The same should be done in touchend:

var touches = null;
  if (event.changedTouches && event.changedTouches.length) {
      //AC: this is original library case
      touches = event.changedTouches;
  } else if (event.originalEvent && event.originalEvent.changedTouches && event.originalEvent.changedTouches.length) {
      //AC: this is fix actually working
      touches = event.originalEvent.changedTouches;
  } else {
      touches = [event];
  }

Version of ngTouch is 1.2.27.

like image 38
alehro Avatar answered Oct 02 '22 00:10

alehro