7

私の AngularJS アプリは、(スワイプなしで) タッチ イベントの開始と停止の両方を検出できる必要があります。たとえば、タッチの開始時 (ユーザーが指を押し下げたままにする) にロジックを実行し、同じタッチが終了する (ユーザーが指を離す) ときに別のロジックを実行する必要があります。このタスクに ngTouch の実装を検討していますが、ngTouch.ngClick ディレクティブのドキュメントには、タップ時にイベントを発生させることしか記載されていません。ngTouch.$swipe サービスは、タッチ イベントの開始と停止を検出できますが、ユーザーがタッチ中に実際にスワイプ (指を水平または垂直に動かした) 場合のみです。誰にもアイデアはありますか?独自のディレクティブを作成する必要がありますか?

4

3 に答える 3

13

2014 年 11 月 25 日更新:

monospaced angular-hammer ライブラリは現在古くなっているため、Hammer.js チームは、hammer v2.0+ でビルドされたryan mullins バージョンを使用することを推奨しています。


私は ngTouch を掘り下げましたが、私が知る限り、タップとスワイプ以外はサポートされていません (この記事の執筆時点では、バージョン 1.2.0)。私は、より成熟したマルチタッチ ライブラリ (hammer.js) と、hammer.js のすべてのマルチタッチ機能を属性ディレクティブとして公開する十分にテストおよび保守された角度モジュール (angular-hammer) を使用することにしました。

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

于 2013-11-14T21:18:07.007 に答える
4

これは良い実装です:

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

于 2016-04-05T00:14:48.227 に答える