Javascript AngularJS:单击目标是否在元素内部?没有jQuery

Javascript AngularJS:单击目标是否在元素内部?没有jQuery,javascript,angularjs,events,onclick,Javascript,Angularjs,Events,Onclick,我有一个slideUp配置区域,当在它外部单击时应该关闭,但当在元素内部单击时当然不会关闭。 我在这里能找到的关于这个主题的所有问题,都是关于隐藏菜单的,在这种情况下,点击目标在哪里并不重要 几个小时后,我设计了一个有效的解决方案(在中可用),但我不得不使用jQuery测试单击目标是否确实在元素之外 由于我正在学习AngularJS,我希望避免使用jQuery;有人告诉我这是最好的学习方法;) 有没有办法检测到这一点?我打赌这是很明显的,但最琐碎的事情在我目前的舞台上需要几个小时:D 编辑:这里

我有一个slideUp配置区域,当在它外部单击时应该关闭,但当在元素内部单击时当然不会关闭。 我在这里能找到的关于这个主题的所有问题,都是关于隐藏菜单的,在这种情况下,点击目标在哪里并不重要

几个小时后,我设计了一个有效的解决方案(在中可用),但我不得不使用jQuery测试单击目标是否确实在元素之外

由于我正在学习AngularJS,我希望避免使用jQuery;有人告诉我这是最好的学习方法;)

有没有办法检测到这一点?我打赌这是很明显的,但最琐碎的事情在我目前的舞台上需要几个小时:D

编辑:这里真正的问题是检测点击是否在元素之内或之外,而不“吃”任何相关事件。

角度方法是放入一个指令,下面是一个简单的通用指令工作示例,它可以隐藏/显示内容并使用主体隐藏

它不需要jQuery(使用与Angular绑定的jqLite)

编辑: 这是一个版本,它演示了指令不会吞下所有的点击。。。

HTML/CSS解决方案 在整个页面上创建一个图层,单击ng隐藏slideUp,然后您就可以安全地将slideUp元素添加到该图层的顶部了

HTML

CSS

slideUp的z索引为2,因此如果单击它,则不会触发toggleSlideUp

普朗克:

或者 您可以使用
angular.element.bind(文档、函数(事件){…})
传递给回调的
事件
对象有一个
target
属性,可以与slideUp元素进行比较

所以在你的控制器里你可以

angular.element(document).bind(document, function(event){
    if(event.target !== slideUpElement) {
        hideSlideUpElement
    }
}):

投票结束此处的重复项以及@shaunhusain的建议,您应该将任何操纵DOM的角度代码重构为指令。这里有一个Plunker作为例子(没有您正在追逐的散焦功能)@shaunhusain可以捕捉到事件,但它太贪婪了,因为它还可以捕捉配置区域内的合法事件,如@midiq中所示。是的,您是对的,它应该在指令中。我还没到那一章;)我必须纠正我自己:链接问题中的问题做了我希望它做的事情——至少当我在我的开发站点上实现它时。我试图更新,但在那里运行时,我得到了
错误:多个指令[ClickAnywhere Buthere,ngController]要求在:
上隔离作用域。我喜欢您的方法的“角度方式”,但它会产生另一个问题,我在问题注释中也提到了这一点。它是贪婪的,并且“吃掉”元素中任何合法的点击事件。例如,如果您有一个按钮内有
ng click
指令,它将不会被触发。您确定吗?我修改了jsbin以表明这不是真的。请参见答案中的编辑,你是对的!:)这是一个更优雅的解决方案,因为show/hide逻辑完全包含在指令中。模板中的双
是故意的,还是可以省略?不,不能省略,角度模板需要有一个父元素。它是被注入链接函数的元素。是的,我想我在某处读过类似的东西。再次感谢。我无法控制整个文档。我的用例是一个ownCloud应用程序,我只能控制指定的应用程序空间。哪个部分完全不适合你的用例?如果您能够在页面上创建元素并为它们提供css,那么您应该能够做到这一点。请原谅,我承认我不熟悉ownCloud应用程序。ownCloud应用程序有一个div,用于呈现其内容。我只能将
ng click
处理程序附加到文档中的该div。在主标题和导航上的任何点击都不会被捕捉。你不需要捕捉它们来隐藏你的div吗?你能在你的控制器中使用我答案末尾的代码吗?啊,我没有注意到你编辑并添加了一个“可选”部分。是的,这基本上就是@JeremyWeir所建议的
var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope) {
  $scope.slideUp = {show:true};
  $scope.toggleSlideUp = function() {
    $scope.slideUp.show = !$scope.slideUp.show;
  };
});
.mask {
  position:absolute;
  z-index:1;
  top:0;
  bottom:0;
  left:0;
  right:0;
}

.slide-up {
  width:200px;
  height:200px;
  background-color:blue;
  position:absolute;
  top:50%;
  left:50%;
  margin-left:-100px;
  margin-top:-100px;
  z-index:2;
}
angular.element(document).bind(document, function(event){
    if(event.target !== slideUpElement) {
        hideSlideUpElement
    }
}):