我使用以下指令来检测何时在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();
});
}
};
});
在这个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>
它运行良好,当您在div外部单击时,触发函数closeMyPopup(),问题是div具有触发其他功能的按钮。由于某种原因,当调用其他函数时(如单击按钮时)会触发事件单击外部调用closeMyPopup(),按钮位于div内部,因此不应调用外部事件单击。我可以使用另一个指令,它具有正确的行为,并且在您触发另一个函数时不会触发外部的单击?或者我该如何解决这个问题?
我也使用这个其他指令,同样的问题:
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);
});
}
}
}]);
答案 0 :(得分:2)
因为事件正在传播到Window
对象。
- Window
- document
- dialog
- button
在上面的层次结构中,如果在最后一个button
元素上发生了单击事件,则该事件将传播到父元素,直到它到达Window,然后关闭对话框。
解决方案1:
通过将事件作为参数传递并调用event.stopPropagation()
函数来停止每个控制器函数中的事件传播:
<button type="button" class="form-control btn" ng-click="onCancelAnnouncement($event)">Cancel</button>
...
$scope.onCancelAnnouncement($event) {
$event.stopPropagation();
}
解决方案2:
让事件传播并检查目标元素:
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
}
});
答案 1 :(得分:1)
确切地说:事件将呈现给嵌套DOM层次结构中的每个对象,除非并且直到你停止它们的传播。当然,这是设计上的:JavaScript并不认为“我能找到的最内心的人正在聆听这个事件”是唯一可能对它感兴趣的人。 每个人谁说他正在倾听它,谁能够听到它,就会听到它,每一个轮流......除非其中一个明确地宣布进一步传播,JS将会停止寻找其他人发送给它。 (没有人必须“将事件发送到外部容器。”相反,他们只需告诉JS 而不是发送它。)