2013-11-14 7 views
5

La mia app AngularJS deve essere in grado di rilevare sia l'inizio che l'arresto di un evento tattile (senza strisciare). Ad esempio, ho bisogno di eseguire un po 'di logica all'avvio del tocco (l'utente preme il dito e tiene premuto), quindi esegue una logica diversa quando lo stesso tocco termina (l'utente rimuove il dito). Sto cercando di implementare ngTouch per questa attività, ma la documentazione per la direttiva ngTouch.ngClick menziona solo l'attivazione dell'evento alla spina. Il servizio ngTouch. $ Swipe è in grado di rilevare l'inizio e l'interruzione dell'evento tattile, ma solo se l'utente lo ha effettivamente fatto scorrere (spostato il dito orizzontalmente o verticalmente) mentre si toccava. Qualcuno ha qualche idea? Dovrò semplicemente scrivere la mia direttiva?È possibile utilizzare la libreria ngTouch di angular per rilevare un evento di clic lungo (tocco/attesa/rilascio)?

risposta

12

Aggiornamento 11/25/14:

La biblioteca angolare-martello a spaziatura fissa è superata in questo momento, quindi la squadra Hammer.js recommend utilizzare il ryan mullins version, che è costruito nel corso del martello v2.0 +.


ho scavato nel ngTouch e da quello che posso dire che non ha il supporto per qualcosa di diverso rubinetto e colpo (a partire dal momento in cui scriviamo, la versione 1.2.0). Ho optato per una libreria multi-touch più matura (hammer.js) e un modulo angolare ben collaudato e mantenuto (martello angolare) che espone tutte le funzionalità multi-touch di hammer.js come direttive attributo.

https://github.com/monospaced/angular-hammer

+0

Perché puntare a un repository biforcato? –

+7

@ PhươngNguyễn Poiché il repository da biforcarsi è obsoleto, non viene più mantenuto attivamente, non contiene tag di versione e al momento in cui ho postato questo non supportava nemmeno bower. Ho scavato nel codice di tutte le diverse versioni e la versione monospazio è la migliore. – Egg

+5

Inoltre non sono sicuro del motivo per cui così tante persone fanno downvoting di questa risposta. Sarebbe bello se qualcuno di loro pubblicasse ragioni per cui potesse essere migliorato. Ho utilizzato questa soluzione in più progetti angolari di produzione/enterprise ormai da quasi un anno e ha funzionato abbastanza bene, e sin da ora ngTouch ha ancora alcuni problemi seri e manca di supporto per diversi gesti. Se conosci qualche opzione migliore, ti preghiamo di dirlo. – Egg

3

La biblioteca angolare martello spaziatura fissa è superata in questo momento, quindi la squadra Hammer.js recommend utilizzare il ryan mullins version, che è costruito nel corso del martello v2.0 +.

+1

Questa è una buona notizia, grazie! Sono andato avanti e l'ho aggiunto per rispondere per assicurarmi che le persone non lo perdessero. – Egg

3

Si tratta di una buona implementazione: esempio

// pressableElement: pressable-element 
.directive('pressableElement', function ($timeout) { 
    return { 
     restrict: 'A', 
     link: function ($scope, $elm, $attrs) { 
      $elm.bind('mousedown', function (evt) { 
       $scope.longPress = true; 
       $scope.click = true; 

       // onLongPress: on-long-press 
       $timeout(function() { 
        $scope.click = false; 
        if ($scope.longPress && $attrs.onLongPress) { 
         $scope.$apply(function() { 
          $scope.$eval($attrs.onLongPress, { $event: evt }); 
         }); 
        } 
       }, $attrs.timeOut || 600); // timeOut: time-out 

       // onTouch: on-touch 
       if ($attrs.onTouch) { 
        $scope.$apply(function() { 
         $scope.$eval($attrs.onTouch, { $event: evt }); 
        }); 
       } 
      }); 

      $elm.bind('mouseup', function (evt) { 
       $scope.longPress = false; 

       // onTouchEnd: on-touch-end 
       if ($attrs.onTouchEnd) { 
        $scope.$apply(function() { 
         $scope.$eval($attrs.onTouchEnd, { $event: evt }); 
        }); 
       } 

       // onClick: on-click 
       if ($scope.click && $attrs.onClick) { 
        $scope.$apply(function() { 
         $scope.$eval($attrs.onClick, { $event: evt }); 
        }); 
       } 
      }); 
     } 
    }; 
}) 

Usage:

<div pressable-element 
    ng-repeat="item in list" 
    on-long-press="itemOnLongPress(item.id)" 
    on-touch="itemOnTouch(item.id)" 
    on-touch-end="itemOnTouchEnd(item.id)" 
    on-click="itemOnClick(item.id)" 
    time-out="600" 
    >{{item}}</div> 

var app = angular.module('pressableTest', []) 
 

 
.controller('MyCtrl', function($scope) { 
 
    $scope.result = '-'; 
 

 
    $scope.list = [ 
 
     { id: 1 }, 
 
     { id: 2 }, 
 
     { id: 3 }, 
 
     { id: 4 }, 
 
     { id: 5 }, 
 
     { id: 6 }, 
 
     { id: 7 } 
 
    ]; 
 

 
    $scope.itemOnLongPress = function (id) { $scope.result = 'itemOnLongPress: ' + id; }; 
 
    $scope.itemOnTouch = function (id) { $scope.result = 'itemOnTouch: ' + id; }; 
 
    $scope.itemOnTouchEnd = function (id) { $scope.result = 'itemOnTouchEnd: ' + id; }; 
 
    $scope.itemOnClick = function (id) { $scope.result = 'itemOnClick: ' + id; }; 
 
}) 
 

 
.directive('pressableElement', function ($timeout) { 
 
    return { 
 
     restrict: 'A', 
 
     link: function ($scope, $elm, $attrs) { 
 
      $elm.bind('mousedown', function (evt) { 
 
       $scope.longPress = true; 
 
       $scope.click = true; 
 
       $scope._pressed = null; 
 

 
       // onLongPress: on-long-press 
 
       $scope._pressed = $timeout(function() { 
 
        $scope.click = false; 
 
        if ($scope.longPress && $attrs.onLongPress) { 
 
         $scope.$apply(function() { 
 
          $scope.$eval($attrs.onLongPress, { $event: evt }); 
 
         }); 
 
        } 
 
       }, $attrs.timeOut || 600); // timeOut: time-out 
 

 
       // onTouch: on-touch 
 
       if ($attrs.onTouch) { 
 
        $scope.$apply(function() { 
 
         $scope.$eval($attrs.onTouch, { $event: evt }); 
 
        }); 
 
       } 
 
      }); 
 

 
      $elm.bind('mouseup', function (evt) { 
 
       $scope.longPress = false; 
 
       $timeout.cancel($scope._pressed); 
 

 
       // onTouchEnd: on-touch-end 
 
       if ($attrs.onTouchEnd) { 
 
        $scope.$apply(function() { 
 
         $scope.$eval($attrs.onTouchEnd, { $event: evt }); 
 
        }); 
 
       } 
 

 
       // onClick: on-click 
 
       if ($scope.click && $attrs.onClick) { 
 
        $scope.$apply(function() { 
 
         $scope.$eval($attrs.onClick, { $event: evt }); 
 
        }); 
 
       } 
 
      }); 
 
     } 
 
    }; 
 
})
li { 
 
    cursor: pointer; 
 
    margin: 0 0 5px 0; 
 
    background: #FFAAAA; 
 
}
<div ng-app="pressableTest"> 
 
    <div ng-controller="MyCtrl"> 
 
     <ul> 
 
      <li ng-repeat="item in list" 
 
       pressable-element 
 
       on-long-press="itemOnLongPress(item.id)" 
 
       on-touch="itemOnTouch(item.id)" 
 
       on-touch-end="itemOnTouchEnd(item.id)" 
 
       on-click="itemOnClick(item.id)" 
 
       time-out="600" 
 
       >{{item.id}}</li> 
 
     </ul> 
 
     <h3>{{result}}</h3> 
 
    </div> 
 
</div> 
 

 
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

Sulla base: https://gist.github.com/BobNisco/9885852

+1

Bello! Deve essere up-votato. –

Problemi correlati