可以使用angular的ngTouch库来检测长按(触摸/保持/释放到位)事件吗?

时间:2021-11-14 12:49:36

My AngularJS app needs to be able to detect both the start and stop of a touch event (without swiping). For example, I need to execute some logic when the touch begins (user presses down their finger and holds), and then execute different logic when the same touch ends (user removes their finger). I am looking at implementing ngTouch for this task, but the documentation for the ngTouch.ngClick directive only mentions firing the event on tap. The ngTouch.$swipe service can detect start and stop of the touch event, but only if the user actually swiped (moved their finger horizontally or vertically) while touching. Anyone have any ideas? Will I need to just write my own directive?

我的AngularJS应用程序需要能够检测到触摸事件的开始和停止(无需滑动)。例如,我需要在触摸开始时执行一些逻辑(用户按下他们的手指并按住),然后在相同的触摸结束时(用户移开他们的手指)执行不同的逻辑。我正在考虑为此任务实现ngTouch,但ngTouch.ngClick指令的文档仅提及触发事件。 ngTouch。$ swipe服务可以检测触摸事件的开始和停止,但前提是用户在触摸时实际滑动(水平或垂直移动手指)。有人有主意吗?我需要编写自己的指令吗?

3 个解决方案

#1


13  

Update 11/25/14:

The monospaced angular-hammer library is outdated right now, so the Hammer.js team recommend to use the ryan mullins version, which is built over hammer v2.0+.

等宽角锤图书馆现在已经过时了,所以Hammer.js团队建议使用ryan mullins版本,它是用锤子v2.0 +构建的。


I dug into ngTouch and from what I can tell it has no support for anything other than tap and swipe (as of the time of this writing, version 1.2.0). I opted to go with a more mature multi-touch library (hammer.js) and a well tested and maintained angular module (angular-hammer) which exposes all of hammer.js's multi-touch features as attribute directives.

我挖到了ngTouch,从我可以告诉它除了点击和滑动之外的任何东西都没有支持(截至本文撰写时,版本1.2.0)。我选择使用更成熟的多点触控库(hammer.js)和经过良好测试和维护的角度模块(角锤),它将所有hammer.js的多点触控功能作为属性指令。

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

#2


4  

It is a good implementation:

这是一个很好的实现:

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

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

Based on: https://gist.github.com/BobNisco/9885852

基于:https://gist.github.com/BobNisco/9885852

#3


3  

The monospaced angular-hammer library is outdated right now, so the Hammer.js team recommend to use the ryan mullins version, which is built over hammer v2.0+.

等宽角锤图书馆现在已经过时了,所以Hammer.js团队建议使用ryan mullins版本,它是用锤子v2.0 +构建的。

#1


13  

Update 11/25/14:

The monospaced angular-hammer library is outdated right now, so the Hammer.js team recommend to use the ryan mullins version, which is built over hammer v2.0+.

等宽角锤图书馆现在已经过时了,所以Hammer.js团队建议使用ryan mullins版本,它是用锤子v2.0 +构建的。


I dug into ngTouch and from what I can tell it has no support for anything other than tap and swipe (as of the time of this writing, version 1.2.0). I opted to go with a more mature multi-touch library (hammer.js) and a well tested and maintained angular module (angular-hammer) which exposes all of hammer.js's multi-touch features as attribute directives.

我挖到了ngTouch,从我可以告诉它除了点击和滑动之外的任何东西都没有支持(截至本文撰写时,版本1.2.0)。我选择使用更成熟的多点触控库(hammer.js)和经过良好测试和维护的角度模块(角锤),它将所有hammer.js的多点触控功能作为属性指令。

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

#2


4  

It is a good implementation:

这是一个很好的实现:

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

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

Based on: https://gist.github.com/BobNisco/9885852

基于:https://gist.github.com/BobNisco/9885852

#3


3  

The monospaced angular-hammer library is outdated right now, so the Hammer.js team recommend to use the ryan mullins version, which is built over hammer v2.0+.

等宽角锤图书馆现在已经过时了,所以Hammer.js团队建议使用ryan mullins版本,它是用锤子v2.0 +构建的。