我试图在点击弹出窗口外的任何地方时关闭我的Angular-bootstrap popover
。根据这个问题的答案,现在可以通过利用新的popover-is-open
属性来完成(在版本0.13.4中):Hide Angular UI Bootstrap popover when clicking outside of it
目前我的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>
...和我的相关控制器代码:
vm.togglePopover = false;
vm.openTogglePopover = function() {
vm.togglePopover = !vm.togglePopover;
};
这对于在单击上面引用的按钮时打开/关闭弹出窗口非常有用。我的问题是,当点击弹出窗口外的任何地方时,我如何扩展此功能以关闭弹出窗口?我如何设置事件处理来完成此任务?
答案 0 :(得分:13)
由于angular-ui 1.0.0,工具提示和弹出窗口有一个新的outsideClick
触发器(在this pull request中引入:
<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>
答案 1 :(得分:11)
首先,如果您希望弹出窗口在任何点击时关闭,而不仅仅是弹出窗口外的弹出窗口,您可以使用现有的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>
这里的诀窍是放弃周围的<div>
并将popover-trigger="focus"
放在按钮上。
如果您只需要为弹出窗口内容之外的点击关闭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);
});
}
}
});
然后,在弹出模板中,使用最外层元素的指令:
<div click-outside="level.closePopover()">
... (actual popover content goes here)
</div>
最后,在您的控制器中,实现closePopover
功能:
vm.closePopover = function () {
vm.togglePopover = false;
};
我们在这里做的是:
close-popover
指令的元素之外:
close-popover
这不是最干净的解决方案,因为您必须从弹出模板中调用控制器方法,但这是我提出的最佳解决方案。
答案 2 :(得分:2)
如果我理解正确,当用户点击几乎任何地方(除了在弹出窗口内部)时,你想要关闭弹出窗口,除非实际关闭按钮。这可以通过事件监听器完成:
$('html').click(function() {
if(!$(event.target).is('#foo')) {
// Code to hide/remove popovers
}
});
查看此plunkr。
或者,在您的具体情况中:
$('html').click(function() {
if(!$(event.target).is('.my-popover-class')) {
vm.togglePopover = false;
}
})
答案 3 :(得分:1)
您需要自己进行事件处理,就像使用新的*-is-open
属性一样,没有事件处理。
如果您不需要对打开/关闭弹出窗口进行编程控制,那么您可以使用内置的focus
触发器来提供您想要的内容。
答案 4 :(得分:1)
单击弹出窗口外的任何位置时关闭弹出框
前段时间我发现这个答案很有用:How to dismiss a Twitter Bootstrap popover by clicking outside?
我在我的一个演示中使用的代码(混合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');
}
});
};
我还建议看看之间的区别: