2013-11-14 9 views
5

私のAngularJSアプリは、タッチイベントの開始と停止(スワイプなし)の両方を検出できる必要があります。例えば、タッチが始まると(ユーザーが指を押し続けて保持する)、同じタッチが終了したとき(ユーザーが指を離したとき)に異なるロジックを実行する必要があります。私はこのタスクのためにngTouchを実装することを検討していますが、ngTouch.ngClickディレクティブのドキュメンテーションでは、イベントをタップで起動することしか記述されていません。 ngTouch。$スワイプサービスは、タッチイベントの開始と停止を検出できますが、タッチしている間にユーザーが実際にスワイプした(指を水平または垂直に動かした場合のみ)。誰にでもアイデアはありますか?私自身の指令を書く必要がありますか?angleのngTouchライブラリを使用して、長いクリック(場所のタッチ/保持/解放)イベントを検出できますか?

答えて

12

更新11/25/14:Hammer.jsチームrecommendはハンマーのv2.0 +の上に構築されているryan mullins versionを使用するよう

等幅、角度、ハンマーライブラリは、今時代遅れです。


私はngTouchに、私はそれが(バージョン1.2.0、この記事の執筆時点のような)タップとスワイプ以外をサポートしていません伝えることができるものから掘りました。より成熟したマルチタッチライブラリ(hammer.js)とよくテストされ、維持された角度モジュール(角ハンマー)を使用することにしました。これは、hammer.jsのマルチタッチ機能をすべて属性ディレクティブとして公開します。 Hammer.jsチームrecommendはハンマーのv2.0 +の上に構築されているryan mullins versionを使用するよう

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

+0

フォークされたレポを指しているのはなぜですか? –

+7

@PhươngNguyễnフォークされたレポは古いもので、もはや積極的に管理されておらず、バージョンタグも含まれていないため、投稿した時点ではバワーもサポートされませんでした。私はすべての異なるバージョンのコードを掘り出した。モノスペースのバージョンが最高だ。 – Egg

+5

なぜこのように多くの人々がこの答えを下降させているのかも分かりません。彼らのうちの何人かがなぜ改善することができるのかという理由を記しておくとよいでしょう。私はこのソリューションを複数のエンタープライズ/プロダクション用の角度プロジェクトに1年近く使ってきましたが、かなりうまくいきました。現在、ngTouchはまだいくつかの重大な問題を抱えており、異なるジェスチャーをサポートしていません。より良いオプションが分かっているなら、教えてください。 – Egg

3

等幅、角度、ハンマーライブラリは、今時代遅れです。

+1

それは良いIntelです、ありがとう!私は先に進み、人々がそれを見逃さないように答えるためにそれを加えました。 – Egg

3

それは良い実装です:

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

使用例:

<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>

に基づいて:https://gist.github.com/BobNisco/9885852

+1

美しい!投票する必要があります。 –

関連する問題