点击此处所有活动

Pic*_*els 35 javascript angularjs

想知道我将如何实现"点击无处不在但在此元素上"活动.

我有一些东西可以与文件浏览器中的文件列表进行比较.您可以选择某些元素,但如果您在元素控制器外部单击,则需要取消选择所有元素.

在此输入图像描述

添加了屏幕截图以使其更加清晰.所以我想要做的是,如果我点击任何地方,但语言元素,它应该触发一个事件.

更新

澄清我不是问我如何用jQuery做到这一点.

Ben*_*esh 68

编辑:这个陈旧的答案中有几个问题.

*另外:标记社区Wiki(对我来说没有分数),因为错误

  1. N要求N使用该指令.对于具有匹配表达式的相同范围内的用途,这可能是不可取的.

  2. 没有什么可以扯掉事件处理器!!!! 坏!坏!坏!

所以,我正在更新这个答案.希望它不会给任何人带来太多麻烦.

更新的答案

这是一个新的plunker,修复了这些问题 ......个别应用程序开发人员可能遇到其他可能的问题.这只是如何处理此问题的一个示例.

app.factory('clickAnywhereButHereService', function($document){
  var tracker = [];

  return function($scope, expr) {
    var i, t, len;
    for(i = 0, len = tracker.length; i < len; i++) {
      t = tracker[i];
      if(t.expr === expr && t.scope === $scope) {
        return t;    
      }
    }
    var handler = function() {
      $scope.$apply(expr);
    };

    $document.on('click', handler);

    // IMPORTANT! Tear down this event handler when the scope is destroyed.
    $scope.$on('$destroy', function(){
      $document.off('click', handler);
    });

    t = { scope: $scope, expr: expr };
    tracker.push(t);
    return t;
  };
});

app.directive('clickAnywhereButHere', function($document, clickAnywhereButHereService){
  return {
    restrict: 'A',
    link: function(scope, elem, attr, ctrl) {
      var handler = function(e) {
        e.stopPropagation();
      };
      elem.on('click', handler);

      scope.$on('$destroy', function(){
        elem.off('click', handler);
      });

      clickAnywhereButHereService(scope, attr.clickAnywhereButHere);
    }
  };
});
Run Code Online (Sandbox Code Playgroud)

原始答案(修复了事件处理程序的拆卸)

你已经找到了一个答案,但是我已经你的一个答案放在一起,向你展示它缺少的东西.

app.directive('clickAnywhereButHere', function($document){
  return {
    restrict: 'A',
    link: function(scope, elem, attr, ctrl) {
      var elemClickHandler = function(e) {
        e.stopPropagation();
      };

      var docClickHandler = function() {
        scope.$apply(attr.clickAnywhereButHere);
      };

      elem.on('click', elemClickHandler);
      $document.on('click', docClickHandler);

      // teardown the event handlers when the scope is destroyed.
      scope.$on('$destroy', function() {
        elem.off('click', elemClickHandler);
        $document.off('click', docClickHandler);
      });
    }
  }
})
Run Code Online (Sandbox Code Playgroud)

HTML

<a click-anywhere-but-here="clickedSomewhereElse()" 
  ng-click="clickedHere()">Don't Click Me!</a>
Run Code Online (Sandbox Code Playgroud)

  • 仅供参考,$ eval和$ apply可以组合成一行:`scope.$ apply(attr.clickAnywhereButHere);` (2认同)

Max*_*tes 28

当前接受的答案的问题是,如果你多次使用该指令,那么附加指令的每个DOM元素都会阻止冒泡(所以如果你有两个元素,并且你点击其中任何一个,那么两者的回调将是阻止).

编辑 - 避免jQuery,清理 - 在你的作用域上定义一个函数,并直接将它传递给这个指令(没有括号),并在调用时将事件传递给它.

app.directive('clickAnywhereButHere', function($document, $parse) {
    return {
        restrict: 'A',
        scope: {
            callback : '=clickAnywhereButHere'
        },
        link: function(scope, element, attr, ctrl) {
            var handler = function(event) {
                if (!element[0].contains(event.target)) {
                    scope.callback(event);
                 }
            };

            $document.on('click', handler);
            scope.$on('$destroy', function() {
                $document.off('click', handler);
            });
        }
    }
});
Run Code Online (Sandbox Code Playgroud)

在HTML中的用法

<a click-anywhere-but-here="myFunction"></a>
Run Code Online (Sandbox Code Playgroud)

控制器中的用法

 $scope.myFunction = function (event) { ... } 
Run Code Online (Sandbox Code Playgroud)

-

请注意,您可能需要换scope.callback(event)scope.$apply()

  • 另请注意,如果您不想使用隔离范围,可以轻松删除范围声明,并在处理程序内部使用blesh的答案中的语法:`scope.$ apply(attr.clickAnywhereButHere)` (2认同)

Ste*_*fan 7

如果您有很多需要此指令的元素,那么这是另一个性能优化的解决方案.(示例包含100多行的列表,每个行都有此指令)

这将始终只包含一个$文档侦听器

angular.module('app').directive('clickElsewhere', ['$document', function ($document) {
return {
  link: function postLink(scope, element, attr) {

    var elsewhere = true;

    element.on('click', function(e) {
      elsewhere = false;
      $document.off('click', clickElsewhere);
      $document.on('click', clickElsewhere);
    });

    var clickElsewhere = function() {
      if (elsewhere) {
        scope.$apply(attr.clickElsewhere);
        $document.off('click', clickElsewhere);
      }
      elsewhere = true;
    };

  }
};
}]);
Run Code Online (Sandbox Code Playgroud)

Max Bates解决方案的问题是所有指令都为$ document.on添加了一个监听器('click',function(...)); 出现性能问题的事件.

已接受答案的问题已经说明了Max Bates.