AngularJS下拉指令在外部点击时隐藏

我正在尝试使用checkbox和filter选项创build多选下拉列表。 我试图让隐藏的列表与我单击外面,但无法弄清楚如何。 感谢你的帮助。

注意,你的解决scheme(在问题中提到的Plunker)在打开第二个popup窗口(在具有多个select的页面上)时不closures其他框的popup窗口。

通过点击一个框来打开一个新的popup窗口,点击事件将一直停止。 该事件将永远不会达到任何其他打开的popup(closures它们)。

我通过删除event.stopPropagation();来解决这个问题event.stopPropagation(); 行和匹配popup窗口的所有子元素。

如果事件元素不匹配popup窗口的任何子元素,则只会closurespopup窗口。

我将指令代码更改为以下内容:

select.html(指令代码)

 link: function(scope, element, attr){ scope.isPopupVisible = false; scope.toggleSelect = function(){ scope.isPopupVisible = !scope.isPopupVisible; } $(document).bind('click', function(event){ var isClickedElementChildOfPopup = element .find(event.target) .length > 0; if (isClickedElementChildOfPopup) return; scope.$apply(function(){ scope.isPopupVisible = false; }); }); } 

我分叉你的掠夺者,并应用这些变化:

Plunker:在外面点击隐藏popupdiv

截图:

Plunker截图

这是一个旧的post,但如果这有助于这里的任何人都是一个外部点击的工作示例,不依赖于任何东西,但angular度。

 module('clickOutside', []).directive('clickOutside', function ($document) { return { restrict: 'A', scope: { clickOutside: '&' }, link: function (scope, el, attr) { $document.on('click', function (e) { if (el !== e.target && !el[0].contains(e.target)) { scope.$apply(function () { scope.$eval(scope.clickOutside); }); } }); } } }); 

好的,我不得不打电话给$ apply(),因为事件发生在angular度世界之外(按照文档)。

  element.bind('click', function(event) { event.stopPropagation(); }); $document.bind('click', function(){ scope.isVisible = false; scope.$apply(); }); 

我通过听一个像这样的全局点击事件来实现它:

 .directive('globalEvents', ['News', function(News) { // Used for global events return function(scope, element) { // Listens for a mouse click // Need to close drop down menus element.bind('click', function(e) { News.setClick(e.target); }); } }]) 

事件本身然后通过新闻服务广播

 angular.factory('News', ['$rootScope', function($rootScope) { var news = {}; news.setClick = function( target ) { this.clickTarget = target; $rootScope.$broadcast('click'); }; }]); 

然后,您可以在任何需要的地方收听广播。 这是一个示例指令:

 .directive('dropdown', ['News', function(News) { // Drop down menu für the logo button return { restrict: 'E', scope: {}, link: function(scope, element) { var opened = true; // Toggles the visibility of the drop down menu scope.toggle = function() { element.removeClass(opened ? 'closed' : 'opened'); element.addClass(opened ? 'opened' : 'closed'); }; // Listens for the global click event broad-casted by the News service scope.$on('click', function() { if (element.find(News.clickTarget.tagName)[0] !== News.clickTarget) { scope.toggle(false); } }); // Init scope.toggle(); } } }]) 

我希望它有帮助!

有一个很酷的指令称为angular-click-outside 。 你可以在你的项目中使用它。 这是非常简单的使用:

https://github.com/IamAdamJowett/angular-click-outside

我对所提供的答案并不完全满意,所以我自己做了。 改进:

  • 更多的防御性更新范围。 将检查是否正在申请/摘要正在进行中
  • 当用户按下退出键时,div也会closures
  • 当div被closures时,窗口事件被解除绑定(防止泄漏)
  • 当范围被破坏时,窗口事件被解除绑定(防止泄漏)

    函数链接(范围,$元素,属性,$窗口){

     var el = $element[0], $$window = angular.element($window); function onClick(event) { console.log('window clicked'); // might need to polyfill node.contains if (el.contains(event.target)) { console.log('click inside element'); return; } scope.isActive = !scope.isActive; if (!scope.$$phase) { scope.$apply(); } } function onKeyUp(event) { if (event.keyCode !== 27) { return; } console.log('escape pressed'); scope.isActive = false; if (!scope.$$phase) { scope.$apply(); } } function bindCloseHandler() { console.log('binding window click event'); $$window.on('click', onClick); $$window.on('keyup', onKeyUp); } function unbindCloseHandler() { console.log('unbinding window click event'); $$window.off('click', onClick); $$window.off('keyup', onKeyUp); } scope.$watch('isActive', function(newValue, oldValue) { if (newValue) { bindCloseHandler(); } else { unbindCloseHandler(); } }); // prevent leaks - destroy handlers when scope is destroyed scope.$on('$destroy', function() { unbindCloseHandler(); }); 

    }

我直接进入链接函数$window 。 然而,你不需要完全做到这一点,以获得$window

 function directive($window) { return { restrict: 'AE', link: function(scope, $element, attributes) { link.call(null, scope, $element, attributes, $window); } }; }