如何在用户单击其子元素时防止父级单击事件?AngularJS

18

我有一个带有 ng-click 属性的 <div>,但是这个 <div> 有一个包含 子元素ng-click 指令。

问题在于,子元素上的点击事件也会触发 父元素的点击事件

当我点击其子元素时,如何防止父元素的点击事件?

这里是 jsfiddle 来说明我的情况。

感谢您的帮助。

编辑

以下是我的代码:

<body ng-app ng-controller="TestController">
<div id="parent" ng-click="parentClick()">
    <div id="child" ng-click="childClick()"></div>

    <p ng-bind="elem"></p>
</div>

<div><p style="text-align:center" ng-bind="childElem"></p></div>
</body>

<script>
function TestController($scope) {
    $scope.parentClick = function() {
        $scope.elem = 'Parent';
    }

    var i = 1;
    $scope.childClick = function() {
        $scope.elem = 'Child';
        $scope.childElem = 'Child event triggered x' + i;
        i++;
    }
}
</script>

要么关闭子处理程序的事件冒泡,要么在处理程序中使用event.target / this / yourFrameworksImplementationOfEventTarget来检查被单击的内容。 - Shilly
5个回答

27

您应该使用event.stopPropagation()方法。 参见:http://jsfiddle.net/qu86oxzc/3/

<div id="child" ng-click="childClick($event)"></div>

$scope.childClick = function($event) {
    $event.stopPropagation();
    ...
}

好的,现在我感觉有点傻,但是非常感谢,这正是我想要的。 因为通常情况下我从不传递元素,所以我没有考虑过它。但是除了 stopPropagation 之外,还有其他方法可以实现这个吗? - KeizerBridge
你可以像这样做:https://dev59.com/OVwX5IYBdhLWcg3w4Ss3#33281294,但我认为这样做真的很丑陋。阻止事件向上冒泡是正确的做法(在我看来)你也可以查看事件的目标(如果$event.target === childElement) - Pieter Willaert

7
使用 event.stopPropagation 来停止事件从子事件处理程序往上冒泡到 DOM 树中。 更新后的演示

function TestController($scope) {
  $scope.parentClick = function() {

    $scope.elem = 'Parent';
  }

  var i = 1;
  $scope.childClick = function(e) {
    $scope.elem = 'Child';
    $scope.childElem = 'Child event triggered x' + i;
    i++;

    e.stopPropagation(); // Stop event from bubbling up
  }
}
body {
  width: 100%;
  height: 100%;
  overflow: hidden;
}
#parent {
  width: 100px;
  height: 100px;
  position: relative;
  z-index: 1;
  margin: 10px auto 0 auto;
  background-color: #00acee;
  border-radius: 2px;
  cursor: pointer;
}
#parent:hover {
  opacity: 0.5;
}
#child {
  width: 20px;
  height: 20px;
  position: absolute;
  top: 10px;
  right: 10px;
  z-index: 2;
  background-color: #FFF;
  border-radius: 2px;
  cursor: pointer;
}
#child:hover {
  opacity: 0.5;
}
#parent p {
  width: 100%;
  position: absolute;
  bottom: 0px;
  text-align: center;
  color: #FFF;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.1/angular.min.js"></script>

<body ng-app ng-controller="TestController">
  <div id="parent" ng-click="parentClick()">
    <div id="child" ng-click="childClick($event)"></div>
    <!--                                 ^^^^^^^     -->
    <p ng-bind="elem"></p>
  </div>
  <div>
    <p style="text-align:center" ng-bind="childElem"></p>
  </div>
</body>


5
同样,您也可以像使用它一样使用此功能。
<div id="child" ng-click="childClick();$event.stopPropagation();"></div>

2
即使Pieter Willaert的回答更加优美,我通过一个简单的布尔检查更新了您的代码片段:

http://jsfiddle.net/qu86oxzc/6/

function TestController($scope) {
    $scope.boolean = false;
    $scope.parentClick = function () {
        if (!$scope.boolean) $scope.elem = 'Parent';
        $scope.toggleBoolean();
    }

    var i = 1;
    $scope.childClick = function () {
        $scope.boolean = true;
        $scope.elem = 'Child';
        $scope.childElem = 'Child event triggered x' + i;
        i++;
    }

    $scope.toggleBoolean = function () {
        $scope.boolean = !$scope.boolean;
    }
}

1
您还可以尝试$event.stopPropagation();。将其写在子函数之后。它的作用类似于preventdefault
<body ng-app ng-controller="TestController">
<div id="parent" ng-click="parentClick()">
    <div id="child" ng-click="childClick();$event.stopPropagation();"></div>

    <p ng-bind="elem"></p>
</div>

<div><p style="text-align:center" ng-bind="childElem"></p></div>
</body>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接