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

Posted

技术标签:

【中文标题】可以使用 Angular 的 ngTouch 库来检测长按(触摸/按住/释放到位)事件吗?【英文标题】:Can angular's ngTouch library be used to detect a long click (touch/hold/release in place) event? 【发布时间】:2013-11-27 21:40:03 【问题描述】:

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

【问题讨论】:

【参考方案1】:

2014 年 11 月 25 日更新:

等宽 angular-hammer 库现在已经过时,因此 Hammer.js 团队 recommend 使用基于hammer v2.0+ 构建的ryan mullins version。


我研究了 ngTouch,据我所知,它不支持任何东西,除了点击和滑动(截至撰写本文时,版本 1.2.0)。我选择使用更成熟的多点触控库(hammer.js)和经过良好测试和维护的角度模块(angular-hammer),它将hammer.js 的所有多点触控功能作为属性指令公开。

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

【讨论】:

@PhươngNguyễn 因为它派生出来的 repo 较旧,不再积极维护,不包含版本标签,而且在我发布时也不支持 bower。我挖掘了所有不同版本的代码,等宽版本是最好的。 也不知道为什么这么多人反对这个答案。如果他们中的一些人能发布原因以便改进,那就太好了。我已经在多个企业/生产角度项目中使用这个解决方案将近一年了,它运行得很好,到目前为止,ngTouch 仍然存在一些严重的问题,并且缺乏对不同手势的支持。如果您知道任何更好的选择,请告知。 是我否决了答案。我已经评论了原因。虽然我同意为了建议一个处理触摸事件的库,你的答案是好的。除非有正当理由不这样做,否则我会始终记入回购的原始所有者。 @PhươngNguyễn 这不是信用问题(有兴趣的人可以通过 github 看到谁开发了原始库),而是提供一个当前/有效的库以供使用。原版已经过时了,我不会在生产中使用它,那我为什么要在这里指出人们呢?欢迎来到开源软件的世界。仅供参考:其他几个人对答案投了反对票(取消了赞成票),没有发表评论。 @Egg “仅供参考:其他几个人在没有评论的情况下对答案投了反对票(取消了赞成票)。”。欢迎来到*** :)【参考方案2】:

这是一个很好的实现:

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

【讨论】:

【参考方案3】:

等宽 angular-hammer 库现在已经过时,因此 Hammer.js 团队 recommend 使用基于hammer v2.0+ 构建的ryan mullins version。

【讨论】:

这是一些很好的情报,谢谢!我继续添加它以确保人们不会错过它。

以上是关于可以使用 Angular 的 ngTouch 库来检测长按(触摸/按住/释放到位)事件吗?的主要内容,如果未能解决你的问题,请参考以下文章

Angular 4 动画下拉菜单

Angular基础 HTTP & Routing

Angular 2 模块/应用程序结构

如何使用 Angular 在模块文件中进行 REST 调用

使用 ng-click 或 jquery 检测平板电脑上的长按

角度性能跟踪