AngularJS: ngTouch 300ms Delay

2019-01-30 03:27发布

问题:

This Plunkr has 2 links. The one on the left side is using the ng-click directive with the on angular-touch module inserted. As said in the angular touch module description for ng-click, the ng-click link should not have a 300ms delay. But if you test it on mobile devices, this is still the case.

So is plunkr preventing the correct functionality because its executed in an iFrame or something like that or is it required to insert Fastclick.js into the project for the directive to work correctly ? I don't get it, please help.

Example: http://plnkr.co/NRRrmMFaIKg2zLu5C1Tg

edit: the example in the angularjs docs ist not working either. They didn't even inserted the angular-touch module.

回答1:

Because angulars ngTouch module is only removing the 300ms delay on ng-click directives, i'm using fastclick.js now which harmonates perfectly fine with angular.

At the beginning it did not work for me, because I attached the Fastclick library before its script was loaded, before the DOM was ready. I fixed this by wrapping the function in the run block of my angular app. This function executes code after the DOM is ready.

angular.module('myModule', []).
  run(function() {
    FastClick.attach(document.body);
  });

This way is suggested by the latest screencast on the angularjs youtube channel.



回答2:

I've solved this by writing my own directive that listens for both touchstart and mousedown events (or touchend / mouseup, etc.). To de-dupe, I set a flag when a touch event happens, and if the flag is set I ignored all mouse events (since touch events happen before mouse events, not de-duping would result in double fires on mobile devices).

appControllers.controller('AppCtrl', ['$scope',
 function($scope) {
  $scope._usingTouch = false;
  /* app code */
}]).directive('lkClick', [function() {
  return function(scope, element, attr) {
    var fn = function() {
      scope.$apply(function() { 
          scope.$eval(attr.lkClick); 
        });
    }

    element.on('touchstart', function(event) {
        scope._usingTouch = true;
        lk();
    });

    element.on('mousedown', function(event) {
      if(!scope._usingTouch)
        lk();
    });
  };
}]);

Then you can add the lk-click="javascript()" directive in your app's html.

Using Fastclick is easier and quicker, but this is more customizable and doesn't require you to load Fastclick code.



回答3:

   // Evita doble tap en dispositivos mobiles
    var TIME_BETWEEN_CLICK = 0;
    App.directive('ngSubmit', function () {
      return {
        restrict: 'A',
        replace: false,
        link: function (scope, el, attrs) {
          el.bind('submit', function (e) {
            if ((new Date().getTime() - TIME_BETWEEN_CLICK) > 300) {
              TIME_BETWEEN_CLICK = new Date().getTime();
            } else {
              e.stopImmediatePropagation();
            }
          });
        }
      };
    });

    App.directive('ngClick', function () {
      return {
        restrict: 'A',
        replace: false,
        link: function (scope, el) {
          el.bind('click', function (e) {
            if ((new Date().getTime() - TIME_BETWEEN_CLICK) > 300) {
              TIME_BETWEEN_CLICK = new Date().getTime();
            } else {
              e.stopImmediatePropagation();
            }
          });
        }
      };
    });