187

这是一个例子。假设我想要像很多网站一样叠加图像。因此,当您单击缩略图时,整个窗口上会出现一个黑色叠加层,并且较大版本的图像会在其中居中。单击黑色叠加层将其关闭;单击图像将调用显示下一张图像的函数。

的HTML:

<div ng-controller="OverlayCtrl" class="overlay" ng-click="hideOverlay()">
    <img src="http://some_src" ng-click="nextImage()"/>
</div>

的JavaScript:

function OverlayCtrl($scope) {
    $scope.hideOverlay = function() {
        // Some code to hdie the overlay
    }
    $scope.nextImage = function() {
        // Some code to find and display the next image
    }
}

问题在于,使用此设置,如果您单击图像,nextImage()则会hideOverlay()调用 和 。但我想要的只是nextImage()被调用。

nextImage()我知道您可以像这样在函数中捕获和取消事件:

if (window.event) {
    window.event.stopPropagation();
}

...但是我想知道是否有更好的 AngularJS 方法来做这件事,它不需要我在覆盖层内的元素上的所有函数前面加上这个片段。

4

10 回答 10

198

@JosephSilber 说了什么,或者将 $event 对象传递给ng-click回调并停止其中的传播:

<div ng-controller="OverlayCtrl" class="overlay" ng-click="hideOverlay()">
  <img src="http://some_src" ng-click="nextImage($event)"/>
</div>
$scope.nextImage = function($event) {
  $event.stopPropagation();
  // Some code to find and display the next image
}
于 2013-03-04T02:30:49.547 回答
174

使用$event.stopPropagation()

<div ng-controller="OverlayCtrl" class="overlay" ng-click="hideOverlay()">
    <img src="http://some_src" ng-click="nextImage(); $event.stopPropagation()" />
</div>

这是一个演示:http ://plnkr.co/edit/3Pp3NFbGxy30srl8OBmQ?p=preview

于 2013-03-04T02:19:23.780 回答
101

我喜欢为此使用指令的想法:

.directive('stopEvent', function () {
    return {
        restrict: 'A',
        link: function (scope, element, attr) {
            element.bind('click', function (e) {
                e.stopPropagation();
            });
        }
    };
 });

然后使用如下指令:

<div ng-controller="OverlayCtrl" class="overlay" ng-click="hideOverlay()">
    <img src="http://some_src" ng-click="nextImage()" stop-event/>
</div>

如果你愿意,你可以让这个解决方案更通用,就像对另一个问题的回答一样:https ://stackoverflow.com/a/14547223/347216

于 2013-11-07T20:52:58.893 回答
32

有时,这样做可能最有意义:

<widget ng-click="myClickHandler(); $event.stopPropagation()"/>

我选择这样做是因为我不想myClickHandler()在使用它的许多其他地方停止事件传播。

当然,我本可以在处理函数中添加一个布尔参数,但stopPropagation()它的意义远不止true.

于 2014-08-14T05:40:14.040 回答
9

这对我有用:

<a href="" ng-click="doSomething($event)">Action</a>

this.doSomething = function($event) {
  $event.stopPropagation();
  $event.preventDefault();
};
于 2016-09-01T08:48:54.840 回答
4

如果您不想将停止传播添加到所有链接,这也可以。更具可扩展性。

$scope.hideOverlay( $event ){

   // only hide the overlay if we click on the actual div
   if( $event.target.className.indexOf('overlay') ) 
      // hide overlay logic

}
于 2013-09-19T11:15:18.457 回答
0

如果您在模板的父元素上插入 ng-click="$event.stopPropagation",stopPropogation 将在树上冒泡时被捕获,因此您只需为整个模板编写一次。

于 2016-04-21T02:56:15.497 回答
0
<div ng-click="methodName(event)"></div>

IN控制器使用

$scope.methodName = function(event) { 
    event.stopPropagation();
}
于 2017-06-07T02:41:58.143 回答
0

您可以在其上注册另一个指令,ng-click以修改默认行为ng-click并停止事件传播。这样您就不必$event.stopPropagation手动添加。

app.directive('ngClick', function() {
    return {
        restrict: 'A',
        compile: function($element, attr) {
            return function(scope, element, attr) {
                element.on('click', function(event) {
                    event.stopPropagation();
                });
            };
        }
    }
});
于 2016-07-22T09:41:38.213 回答
0

就我而言event.stopPropagation();,每次按下链接时都会刷新页面,因此我必须找到另一个解决方案。

所以我所做的是在父母身上捕获事件并阻止触发器,如果​​它实际上来自他的孩子,使用event.target.

这是解决方案:

if (!angular.element($event.target).hasClass('some-unique-class-from-your-child')) ...

所以基本上你的父组件的 ng-click 只有在你点击父组件时才有效。如果你点击了孩子,它不会通过这个条件,也不会继续它的流程。

于 2020-10-27T13:32:27.463 回答