web-dev-qa-db-fra.com

AngularJS: ngTouch 300ms Delay

Cette Plunkr a 2 liens. Celui de gauche utilise la directive ng-click avec le module on angular touch inséré. Comme indiqué dans la description du module tactile angulaire pour ng-click, le lien ng-click ne doit pas avoir un délai de 300 ms. Mais si vous le testez sur des appareils mobiles, c'est toujours le cas.

Alors, est-ce que plunkr empêche la fonctionnalité correcte parce qu’elle est exécutée dans un iFrame ou quelque chose du genre ou est-il obligatoire d’insérer Fastclick.js dans le projet pour que la directive fonctionne correctement? Je ne comprends pas, aidez s'il vous plaît.

Exemple: http://plnkr.co/NRrrmMFaIKg2zLu5C1Tg } _

edit: le exemple dans la documentation angularjs ne fonctionne pas non plus. Ils n'ont même pas inséré le module tactile angulaire.

23
strangfeld

Comme le module angulars ngTouch ne supprime que le délai de 300 ms sur les directives ng-click, j'utilise fastclick.js maintenant, ce qui harmonise parfaitement les angles.

Au début, cela ne fonctionnait pas pour moi, car j'avais attaché la bibliothèque Fastclick avant le chargement de son script, avant que le DOM ne soit prêt. J'ai corrigé cela en encapsulant la fonction dans le bloc run de mon application angulaire. Cette fonction exécute le code une fois que le DOM est prêt.

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

Cette méthode est suggérée par le latest screencast sur la chaîne youtube d'angularjs.

56
strangfeld
   // 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();
            }
          });
        }
      };
    });

J'ai résolu ce problème en écrivant ma propre directive qui écoute à la fois les événements touchstart et mousedown (ou touchend/mouseup, etc.). Pour dédoubler, je mets un indicateur lorsqu'un événement tactile se produit, et si l'indicateur est activé, j'ignore tous les événements de souris (puisque les événements tactiles surviennent avant les événements de souris, ne pas dédoubler entraînerait un double tir sur les périphériques mobiles). 

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();
    });
  };
}]);

Ensuite, vous pouvez ajouter la directive lk-click="javascript()" dans le code HTML de votre application.

L'utilisation de Fastclick est plus simple et plus rapide, mais elle est plus personnalisable et ne nécessite pas de charger du code Fastclick.

0
Luke Knepper