【发布时间】:2013-12-09 18:54:02
【问题描述】:
我知道有很多问题问类似的事情。但是没有人真正解决我的问题。
我正在尝试构建一个指令,当鼠标在当前元素外单击时将执行一个表达式。
为什么我需要这个功能?我正在构建一个应用程序,在这个应用程序中,有 3 个下拉菜单,5 个下拉列表(如选择)。所有这些都是角度指令。让我们假设所有这些指令都是不同的。所以我们有 8 个指令。而且它们都需要一个相同的功能:当点击元素的外部时,需要隐藏下拉菜单。
我有 2 个解决方案,但都遇到了问题:
解决方案 A:
app.directive('clickAnywhereButHere', function($document){
return {
restrict: 'A',
link: function(scope, elem, attr, ctrl) {
elem.bind('click', function(e) {
// this part keeps it from firing the click on the document.
e.stopPropagation();
});
$document.bind('click', function() {
// magic here.
scope.$apply(attr.clickAnywhereButHere);
})
}
}
})
这里是解决方案 A 的示例:click here
当你点击第一个下拉菜单,然后工作,然后点击第二个输入,第一个应该隐藏但不是。
解决方案 B:
app.directive('clickAnywhereButHere', ['$document', function ($document) {
directiveDefinitionObject = {
link: {
pre: function (scope, element, attrs, controller) { },
post: function (scope, element, attrs, controller) {
onClick = function (event) {
var isChild = element.has(event.target).length > 0;
var isSelf = element[0] == event.target;
var isInside = isChild || isSelf;
if (!isInside) {
scope.$apply(attrs.clickAnywhereButHere)
}
}
$document.click(onClick)
}
}
}
return directiveDefinitionObject
}]);
这里是解决方案 B 的示例:click here
如果页面中只有一个指令但我的应用程序中没有,则解决方案 A 有效。因为它是防止冒泡,所以首先当我点击 dropdown1 时,显示 dropdown1,然后点击 dropdown2,点击事件被阻止,所以即使我在 dropdown1 之外点击,dropdown1 仍然显示在那里。
解决方案 B 在我现在使用的应用程序中运行。但问题是它会导致性能问题。在应用程序中的任何位置每次单击都会处理太多的单击事件。在我目前的情况下,有 8 个单击事件与文档绑定,因此每次单击执行 8 个函数。这导致我的应用程序非常缓慢,尤其是在 IE8 中。
那么有没有更好的解决方案呢?谢谢
【问题讨论】:
-
如果你提供使用 Plunker/Fiddle 会很棒。
-
在演示中提供一些基本示例。这肯定看起来比它应该的更复杂。
-
解决方案 B 正在污染全局范围。如果这是故意的,那真是糟糕的做法。如果不是,它可能是您的一些问题的根源。
-
您使用的 angularJS 版本是什么?如果我正确理解了您的要求,我已经给出了一个可行的解决方案。
-
各位大佬,例子加了。
标签: javascript angularjs