Click outside div - when div has buttons that fires events - angularjs

巧了我就是萌 提交于 2019-12-11 03:30:46

问题


I'm using the following directive to detect when a click is made outside a div:

app.directive('clickOut', function ($window, $parse) {
return {
    restrict: 'A',
    link: function (scope, element, attrs) {
        var clickOutHandler = $parse(attrs.clickOut);

        angular.element($window).on('click', function (event) {
            if (element[0].contains(event.target)) return;
            clickOutHandler(scope, {$event: event});
            scope.$apply();
        });
    }
  };
});

In this div:

             <div class="panel-body" click-out="closeMyPopup()">                 
                <div class="row clearfix">
                    <div class="col-md-12">
                        <div class="form-inline pull-right">
                            <button type="button" class="form-control btn"  ng-click="onCancelAnnouncement()">Cancel</button>
                            <button type="submit" class="form-control btn" ng-click="onSaveAnnouncement()">Save</button>
                        </div>

                    </div>
                </div>

            </div>

It works well, when you click outside the div, the function closeMyPopup() is triggered, the issue is that the div has buttons that triggers other functions. By some reason when other function is called, (like when the buttons are clicked) the event click outside is triggered calling the closeMyPopup(), the buttons are inside the div so the event click outside should not be called. There's another directive that I can use, that has the correct behavior and not trigger the click outside when you fire another function? Or how can I workaround this?

I also use this other directive, with the same issue:

app.directive("outsideClick", ['$document', '$parse', function      ($document, $parse) {
    return {
           link: function ($scope, $element, $attributes) {
        var scopeExpression = $attributes.outsideClick,
            onDocumentClick = function (event) {
                var isChild = $element.find(event.target).length > 0;

                if (!isChild) {
                    $scope.$apply(scopeExpression);
                }
            };

        $document.on("click", onDocumentClick);

        $element.on('$destroy', function () {
            $document.off("click", onDocumentClick);
        });
    }
  }
}]);

回答1:


Its because the event is being propagated to Window object.

- Window
    - document
        - dialog
           - button

In the above hierarchy, if a click event happens on the last button element, the event will be propagated to the parent element until it reaches Window and then will close your dialog.

Solution 1:

Stop event propagation in each controller function by passing the event as a parameter and calling event.stopPropagation() function:

<button type="button" class="form-control btn"  ng-click="onCancelAnnouncement($event)">Cancel</button>

...

$scope.onCancelAnnouncement($event) {
    $event.stopPropagation();
}

Solution 2:

Let the event be propagated and check the target element:

angular.element($window).on('click', function (event) {
        var target = $(event.target);
        if(target.attr("id") === "anyid") { // or target.hasClass("someclass")
                                            // or target.closest(".some-selector")
            // just ignore
        } else {
            // Do whatever you need 
        }
});



回答2:


Exactly: events will be presented to every object in the nested DOM-hierarchy unless and until you stop their propagation. This, of course, is by design: JavaScript doesn't assume that "the innermost guy I can find who's listening for this event" is the only guy who might be interested in it. Everyone who says he's listening for it, who is in the position to hear it, is going to hear it, each in their turn ... unless one of them explicitly quashes further propagation, at which JS will stop looking for anyone else to send it to. (No one has to "send the event to the outer container." Instead, they only have to tell JS not to send it on.)



来源:https://stackoverflow.com/questions/31210765/click-outside-div-when-div-has-buttons-that-fires-events-angularjs

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!