Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/441.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用AngularJS在同一元素上处理ng click和ng dblclick_Javascript_Angularjs_Angularjs Directive_Angularjs Ng Click - Fatal编程技术网

Javascript 使用AngularJS在同一元素上处理ng click和ng dblclick

Javascript 使用AngularJS在同一元素上处理ng click和ng dblclick,javascript,angularjs,angularjs-directive,angularjs-ng-click,Javascript,Angularjs,Angularjs Directive,Angularjs Ng Click,我一直在寻找AngularJS的单点和双击事件处理,因为AngularJS总是只触发ng click事件,即使我们的元素设置了ng dblclick指令 以下是一些适用于寻求解决方案的人的工作代码: JS: HTML: 所以我的问题是(因为我是AngularJS的新手):有没有经验更丰富的人能为处理这两个事件写一些好的指令 在我看来,最好的方法是改变ng click、ng dblclick的行为,并添加一些“ng sglclick”指令来处理仅单击的代码。 我不知道这是否可能,但我会发现它对

我一直在寻找AngularJS的单点和双击事件处理,因为AngularJS总是只触发ng click事件,即使我们的元素设置了ng dblclick指令

以下是一些适用于寻求解决方案的人的工作代码:

JS:

HTML:


所以我的问题是(因为我是AngularJS的新手):有没有经验更丰富的人能为处理这两个事件写一些好的指令

在我看来,最好的方法是改变ng click、ng dblclick的行为,并添加一些“ng sglclick”指令来处理仅单击的代码。 我不知道这是否可能,但我会发现它对每个人都非常有用


请随意分享您的意见

你可以自己写。我查看了angular如何处理click,并使用我在此处找到的代码对其进行了修改:


mainMod.controller('AppCntrl',['$scope',函数($scope){
$scope.singleClick=function(){
警报(“单击”);
}
$scope.doubleClick=function(){
警报(“双击”);
}
}])
mainMod.directive('sglclick',['$parse',function($parse){
返回{
限制:“A”,
链接:功能(范围、元素、属性){
var fn=$parse(attr['sglclick']);
var延迟=300,点击次数=0,定时器=null;
元素上('click',函数(事件){
点击次数+++;//点击次数
如果(单击===1){
计时器=设置超时(函数(){
作用域:$apply(函数(){
fn(作用域,{$event:event});
}); 
单击=0;//执行操作后,重置计数器
},延误);
}否则{
clearTimeout(计时器);//防止单击操作
单击=0;//执行操作后,重置计数器
}
});
}
};
}])
这里有一个例子


我在试图找到处理双击和同时单击的方法时遇到了一个问题。我用这里的概念取消了最初的点击。如果在延迟之前发生第二次单击,则执行双击操作。如果没有第二次单击,延迟结束后,将运行默认的ngClick操作,并在元素上触发原始事件(并允许像最初一样冒泡)

范例

<div ng-click="singleClick()"><span double-click="doubleClick()">double click me</span></div>

遇到这个,我想我会放弃另一个选择。除了两个关键点外,它与原始海报没有太大区别

1) 没有嵌套的函数声明

2) 我使用$timeout。我经常使用$timeout,即使没有延迟……特别是当我开始承诺做其他工作时。$timeout将在摘要周期结束时触发,以确保对作用域的任何数据更改都得到应用

给定

双击功能将看起来正常:

$scope.doubleClick = function () {

    $timeout(function () {

        //do something with your double click here

    });
};

希望这对某人有所帮助。

格雷格的答案绝对是最简洁的答案。我将在他的答案的基础上提出一个版本,在这个版本中,不需要编写新的代码,也不需要在控制器中使用新的注入

首先要问的是,为什么要用超时来解决这类问题。从本质上讲,它们用于使函数跳过当前事件循环的其余部分,以便执行干净。然而,在angular中,您实际上对摘要循环的工作方式感兴趣。它几乎与您的经典事件处理程序相同,只是有一些细微的差异,这使它非常适合UX。您手头上的一些用来扰乱函数执行顺序的工具包括
scope.$eval
scope.$evalAsync
scope.$apply
scope.$applyAsync

我相信
$apply
s将启动另一个摘要循环,剩下
$eval
s
$eval
将立即在当前
$scope
的上下文中运行包含的任何代码,
$evalAsync
将在摘要循环结束时对要运行的函数进行排队。本质上,
$evalAsync
$timeout
的一个更干净的版本,有一个很大的区别——第一个版本有上下文,并且存在于作用域中

这意味着您实际上可以在同一元素上处理
ng click
ng dblclick
但是,请注意,这仍然会在双击功能之前触发单击功能。这就足够了:

<div ng-controller="MyController">
    <a href="#"
       ng-click="$evalAsync(singleClickAction())"
       ng-dblclick="doubleClickAction()">
       CLICK
    </a>
</div>


.

如果在
双击
上调用
单点
,不会出现任何错误,那么它也可以工作

<div 
    onclick="var scope = angular.element(this).scope(); scope.singleClick();"
    ng-click="null" 
    ng-dblclick="doubleClick()"
></div>

在此处连接答案:

  • 为简单起见使用
  • 创建一个
    指令
    ,如@Rob(此线程中被接受为最佳答案的指令)
  • 通过使用替换
    ngClick
    build-in指令,解决@Rob-answer问题
这里的包含了这个想法的精髓(与这个答案中的片段相同;见下文)

旁注:理想情况下,如果没有为元素定义
ng dblclick
,则不应阻止单次单击(此处是实现此想法的

(函数(角度){
"严格使用",;
var myApp=angular.module('myApp',[]);
控制器('myCtrl',['$scope',函数($scope){
$scope.click=false;
$scope.singleClick=function(){
$scope.click='single';
};
$scope.doubleClick=function(){
$scope.click='double';
};
}]);
//删除buildin ng,单击以解决问题https://stackoverflow.com/a/20445344/4352306
myApp.config(函数($provide){//来源:https://stackoverflow.com/a/23209542/4352306
$provide.decorator('ngClickDirective',['$delegate',函数($delegate){
//$delegate是所有ng clic的数组
.directive('doubleClick', function($timeout, _) {

  var CLICK_DELAY = 300
  var $ = angular.element

  return {
    priority: 1, // run before event directives
    restrict: 'A',
    link: function(scope, element, attrs) {
      var clickCount = 0
      var clickTimeout

      function doubleClick(e) {
        e.preventDefault()
        e.stopImmediatePropagation()
        $timeout.cancel(clickTimeout)
        clickCount = 0
        scope.$apply(function() { scope.$eval(attrs.doubleClick) })
      }

      function singleClick(clonedEvent) {
        clickCount = 0
        if (attrs.ngClick) scope.$apply(function() { scope.$eval(attrs.ngClick) })
        if (clonedEvent) element.trigger(clonedEvent)
      }

      function delaySingleClick(e) {
        var clonedEvent = $.Event('click', e)
        clonedEvent._delayedSingleClick = true
        e.preventDefault()
        e.stopImmediatePropagation()
        clickTimeout = $timeout(singleClick.bind(null, clonedEvent), CLICK_DELAY)
      }

      element.bind('click', function(e) {
        if (e._delayedSingleClick) return
        if (clickCount++) doubleClick(e)
        else delaySingleClick(e)
      })

    }
  }

})
<img src="myImage.jpg" ng-click="singleClick()" ng-dblclick="doubleClick()">
$scope.singleClick = function () {
    if ($scope.clicked) {
        $scope.cancelClick = true;
        return;
    }

    $scope.clicked = true;

    $timeout(function () {
        if ($scope.cancelClick) {
            $scope.cancelClick = false;
            $scope.clicked = false;
            return;
        }

        //do something with your single click here

        //clean up
        $scope.cancelClick = false;
        $scope.clicked = false;
    }, 500);
};
$scope.doubleClick = function () {

    $timeout(function () {

        //do something with your double click here

    });
};
<div ng-controller="MyController">
    <a href="#"
       ng-click="$evalAsync(singleClickAction())"
       ng-dblclick="doubleClickAction()">
       CLICK
    </a>
</div>
<div 
    onclick="var scope = angular.element(this).scope(); scope.singleClick();"
    ng-click="null" 
    ng-dblclick="doubleClick()"
></div>