twitter-bootstrap 单击外部时如何关闭 Angular-bootstrap 弹出窗口
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/32851978/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to close Angular-bootstrap popover when clicking outside
提问by MattDionis
I am attempting to close my Angular-bootstrap popovers when clicking anywhere outside the popovers. According to an answer to this question this can now be accomplished (in version 0.13.4) by utilizing the new popover-is-openattribute: Hide Angular UI Bootstrap popover when clicking outside of it
popover单击弹出窗口外的任何地方时,我试图关闭我的 Angular-bootstrap 。根据对这个问题的回答,现在可以通过使用新popover-is-open属性来完成(在 0.13.4 版中):Hide Angular UI Bootstrappopover when clicking out of it
Currently my HTML looks like so:
目前我的 HTML 看起来像这样:
<div
ng-click="level.openTogglePopover()"
popover-template="level.changeLevelTemplate"
popover-trigger="none"
popover-placement="right"
popover-is-open="level.togglePopover">
<button class="btn btn-default btn-xs" type="button">
<span class="glyphicon glyphicon-sort"></span>
</button>
</div>
...and my relevant controller code:
...和我的相关控制器代码:
vm.togglePopover = false;
vm.openTogglePopover = function() {
vm.togglePopover = !vm.togglePopover;
};
This works great for opening/closing the popover when clicking on the button referenced above. My question is, how would I extend this functionality to close the popover when clicking anywhere outside of the popover? How would I set up my event handling to accomplish this?
当单击上面引用的按钮时,这对于打开/关闭弹出窗口非常有用。我的问题是,当单击弹出框外的任何地方时,我将如何扩展此功能以关闭弹出框?我将如何设置我的事件处理来实现这一点?
采纳答案by DzinX
First of all, if you want the popover to close on anyclick, not only the one outside of your popover, you can do it using existing UI-Bootstrap code:
首先,如果您希望弹出窗口在任何点击时关闭,而不仅仅是弹出窗口之外的那个,您可以使用现有的 UI-Bootstrap 代码来完成:
<button class="btn btn-default btn-xs" type="button"
popover-template="level.changeLevelTemplate"
popover-trigger="focus"
popover-placement="right">
<span class="glyphicon glyphicon-sort"></span>
</button>
The trick here is to drop the surrounding <div>and put the popover-trigger="focus"right on the button.
这里的诀窍是放下周围的东西<div>,把popover-trigger="focus"右边的按钮放在按钮上。
If you need to actually close the popover only for clicks outside the popover content, then it will be more difficult. You need a new directive, like this one:
如果你只需要针对popover内容之外的点击实际关闭popover,那会比较困难。您需要一个新指令,如下所示:
app.directive('clickOutside', function ($parse, $timeout) {
return {
link: function (scope, element, attrs) {
function handler(event) {
if(!$(event.target).closest(element).length) {
scope.$apply(function () {
$parse(attrs.clickOutside)(scope);
});
}
}
$timeout(function () {
// Timeout is to prevent the click handler from immediately
// firing upon opening the popover.
$(document).on("click", handler);
});
scope.$on("$destroy", function () {
$(document).off("click", handler);
});
}
}
});
Then, in your popover template, use the directive on the outermost element:
然后,在您的 popover 模板中,在最外层元素上使用指令:
<div click-outside="level.closePopover()">
... (actual popover content goes here)
</div>
Finally, in your controller, implement the closePopoverfunction:
最后,在您的控制器中,实现以下closePopover功能:
vm.closePopover = function () {
vm.togglePopover = false;
};
What we've done here is:
我们在这里所做的是:
- we're listening on any clicks on the document, and, if the click is outside of the element to which we added our
close-popoverdirective:- we invoke whatever code was the value of
close-popover
- we invoke whatever code was the value of
- we also clean up after ourselves when the directive's scope is destroyed (i.e. when the popover is closed) so that we don't handle the clicks anymore.
- 我们正在监听文档上的任何点击,并且,如果点击位于我们添加
close-popover指令的元素之外:- 我们调用任何代码的值
close-popover
- 我们调用任何代码的值
- 当指令的作用域被销毁时(即当弹出框关闭时),我们也会自己清理,这样我们就不再处理点击了。
It's not the cleanest solution, as you have to invoke the controller method from within the popover template, but it's the best I came up with.
这不是最干净的解决方案,因为您必须从 popover 模板中调用控制器方法,但这是我想出的最好的解决方案。
回答by cdauth
Since angular-ui 1.0.0, there is a new outsideClicktrigger for tooltips and popovers (introduced in this pull request:
从 angular-ui 1.0.0 开始,outsideClick工具提示和弹出框有了新的触发器(在此拉取请求中引入:
<div
uib-popover-template="level.changeLevelTemplate"
popover-trigger="outsideClick"
popover-placement="right">
<button class="btn btn-default btn-xs" type="button">
<span class="glyphicon glyphicon-sort"></span>
</button>
</div>
回答by Tiago
If I understood correctly, you want the popover to close when a user clicks pretty much anywhere except on the inside of the popover itself, barring the actual close button. This could be accomplished with an event listener:
如果我理解正确,您希望当用户单击除弹出窗口本身之外的几乎任何地方时关闭弹出窗口,除非实际关闭按钮。这可以通过事件侦听器来完成:
$('html').click(function() {
if(!$(event.target).is('#foo')) {
// Code to hide/remove popovers
}
});
Check out this plunkr.
看看这个plunkr。
Or, in your specific scenario:
或者,在您的特定场景中:
$('html').click(function() {
if(!$(event.target).is('.my-popover-class')) {
vm.togglePopover = false;
}
})
回答by Mars Robertson
close the popover when clicking anywhere outside of the popover
单击弹出框外的任意位置时关闭弹出框
Some time ago I've found this answer useful: How to dismiss a Twitter Bootstrap popover by clicking outside?
前段时间我发现这个答案很有用:如何通过单击外部来关闭 Twitter Bootstrap 弹出窗口?
Code I used in one of my demos (mixing angularand jQueryevent handling which is probably not recommended)is specific to my needs but may give some idea:
我在我的一个演示中使用的代码(可能不推荐混合angular和jQuery事件处理)特定于我的需求,但可能会提供一些想法:
app.directive("eventlistener", function($rootScope) {
$(window).resize($rootScope.closeAllPopovers); // because Bootstrap popovers don't look good when misplaced
return {
link: function(scope, element, attrs) {
$('body').on('mouseup touchend', $rootScope.closeAllPopovers);
}
};
});
$rootScope.closeAllPopovers = function (e) {
$('[data-toggle="popover"]').each(function () {
if (e) {
if (!$(this).is(e.target) && $(this).has(e.target).length === 0 && $('.popover').has(e.target).length === 0) {
$(this).popover('hide');
}
} else {
// No event passed - closing all popovers programmatically
$(this).popover('hide');
}
});
};
I'd also suggest looking at the difference between:
我还建议查看以下之间的区别:
回答by icfantv
You're going to need to do the event handling yourself as when you use the new *-is-openattributes, there is no event handling.
您将需要自己进行事件处理,因为当您使用新*-is-open属性时,没有事件处理。
If you don't need the programmatic control over opening/closing the popover, then you can use the built in focustrigger to give you what you want.
如果您不需要对打开/关闭弹出窗口的编程控制,那么您可以使用内置focus触发器来满足您的需求。

