简体   繁体   中英

Add click event to element, but not its children in angular

I know this can be done with jQuery as shown here: How to have click event ONLY fire on parent DIV, not children?

$('.foobar').on('click', function(e) {
  if (e.target !== this)
    return;

  alert( 'clicked the foobar' );
});

But in angular, this keyword is not binded to the element when I use something like:

<div ng-dblclick="ctrl.doubleClickHandler($event)">
    parent, event should fire here.
    <div>child, event should not fire here.</div>
</div>

and in my controller:

this.doubleClickHandler = doubleClickHandler;
function doubleClickHandler(event) {
  console.log(this); // this binds to controller
  console.log(event);
}

The event fires , but I need to prevent it from firing when I click on the element's children.

I don't want to hardcode a check on the event.target based on class or attribute because it might change later. Is there anyway to achieve this within the HTML tag, or in JavaScript without hardcoding the element's class or attributes (similar to the technique of binding the this keyword in jQuery)?

You can compare target and currentTarget . The former is the clicked element and the latter is the element with the handler.

function doubleClickHandler(event) {
  if (event.target !== event.currentTarget) return;
  // do something
}

I think you could try something like this:

<div ng-dblclick="ctrl.doubleClickHandler($event) $event.stopPropagation()">

reference: What's the best way to cancel event propagation between nested ng-click calls?

i update the answer by create directive with jquery in your sample.

 var app = angular.module("app", []); app.controller("controller", function ($scope) { var ctrl = this; ctrl.doubleClickHandler = function () { alert("parent clicked") } }); app.directive("directiveName", function () { return { restrict: "A", scope: { click: "&" }, link: function (scope, element, attr) { element.on('click', function (e) { if (e.target !== this) { return; } else { scope.click() } }); } } }) 
 .foobar span { background: red; } 
 <!DOCTYPE html> <html ng-app="app" ng-controller="controller as ctrl"> <head> <title></title> </head> <body> <div click="ctrl.doubleClickHandler()" directive-name class="foobar"> parent <span> child </span> </div> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> </body> </html> 

If your using jquery try this,

<div class="foobar"> .foobar (alert)
      <span>child (no alert)</span>
</div>

$('.foobar').on('click', function(e) {
    if (e.target !== this)
      return;

    $scope.myFunc(e);
});


$scope.myFunc = function(e) {
     $scope.clicked = "Parent Cicked";
    $scope.$apply();
};

DEMO

surely its not leading to a good programmatic skills. Hence you can try below example with angular and JS

<div class="foobar" data-parent="true" ng-click="myFunc($event)"> .foobar (alert)
      <span>child (no alert)</span>
</div>

// add data attribute as data-parent="true"

$scope.myFunc = function(e) {
    if (! e.target.hasAttribute('data-parent'))
        return;

    $scope.clicked = "Parent Cicked";
};

//if clicked element has `data-parent` property do the things.

DEMO

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM