我们能否以与模态相同的方式使弹出窗口被解雇,即。当用户点击它们之外的某个地方时让它们关闭?
不幸的是我不能只使用真正的模态而不是popover,因为模态意味着位置:固定并且不再有弹出窗口。 :(
答案 0 :(得分:435)
更新:更强大的解决方案:http://jsfiddle.net/mattdlockyer/C5GBU/72/
仅适用于包含文字的按钮:
$('body').on('click', function (e) {
//did not click a popover toggle or popover
if ($(e.target).data('toggle') !== 'popover'
&& $(e.target).parents('.popover.in').length === 0) {
$('[data-toggle="popover"]').popover('hide');
}
});
对于包含图标的按钮,使用(此代码在Bootstrap 3.3.6中有错误,请参阅此答案中的下方修复)
$('body').on('click', function (e) {
//did not click a popover toggle, or icon in popover toggle, or popover
if ($(e.target).data('toggle') !== 'popover'
&& $(e.target).parents('[data-toggle="popover"]').length === 0
&& $(e.target).parents('.popover.in').length === 0) {
$('[data-toggle="popover"]').popover('hide');
}
});
对于JS生成的弹出窗口使用'[data-original-title]'
代替'[data-toggle="popover"]'
警告:上述解决方案允许一次打开多个弹出窗口。
请一次一个popover:
更新: Bootstrap 3.0.x,请参阅代码或小提琴http://jsfiddle.net/mattdlockyer/C5GBU/2/
$('body').on('click', function (e) {
$('[data-toggle="popover"]').each(function () {
//the 'is' for buttons that trigger popups
//the 'has' for icons within a button that triggers a popup
if (!$(this).is(e.target) && $(this).has(e.target).length === 0 && $('.popover').has(e.target).length === 0) {
$(this).popover('hide');
}
});
});
这可以处理已经打开但没有点击的弹出窗口的关闭或者没有点击他们的链接。
更新: Bootstrap 3.3.6,see fiddle
修复问题,关闭后需要点击2次才能重新打开
$(document).on('click', function (e) {
$('[data-toggle="popover"],[data-original-title]').each(function () {
//the 'is' for buttons that trigger popups
//the 'has' for icons within a button that triggers a popup
if (!$(this).is(e.target) && $(this).has(e.target).length === 0 && $('.popover').has(e.target).length === 0) {
(($(this).popover('hide').data('bs.popover')||{}).inState||{}).click = false // fix for BS 3.3.6
}
});
});
答案 1 :(得分:52)
$('html').on('mouseup', function(e) {
if(!$(e.target).closest('.popover').length) {
$('.popover').each(function(){
$(this.previousSibling).popover('hide');
});
}
});
如果您点击弹出窗口上的任何地方
,这将关闭所有弹出窗口Bootstrap 4.1的更新
$("html").on("mouseup", function (e) {
var l = $(e.target);
if (l[0].className.indexOf("popover") == -1) {
$(".popover").each(function () {
$(this).popover("hide");
});
}
});
答案 2 :(得分:36)
最简单,最安全的版本,适用于任何引导版本。
演示: http://jsfiddle.net/guya/24mmM/
演示2:点击popover内容时不解雇 http://jsfiddle.net/guya/fjZja/
演示3:多个弹出窗口: http://jsfiddle.net/guya/6YCjW/
简单地调用此行将取消所有弹出窗口:
$('[data-original-title]').popover('hide');
使用此代码点击外部时,关闭所有弹出窗口:
$('html').on('click', function(e) {
if (typeof $(e.target).data('original-title') == 'undefined') {
$('[data-original-title]').popover('hide');
}
});
上面的代码段会在主体上附加点击事件。 当用户单击一个弹出框时,它将表现正常。 当用户点击不是弹出窗口的东西时,它将关闭所有弹出窗口。
它也适用于使用Javascript启动的弹出窗口,而不是其他一些不起作用的示例。 (见演示)
如果你不想在点击popover内容时忽略,请使用此代码(参见第二个演示的链接):
$('html').on('click', function(e) {
if (typeof $(e.target).data('original-title') == 'undefined' && !$(e.target).parents().is('.popover.in')) {
$('[data-original-title]').popover('hide');
}
});
答案 3 :(得分:20)
使用bootstrap 2.3.2,您可以将触发器设置为“焦点”,它只是起作用:
$('#el').popover({trigger:'focus'});
答案 4 :(得分:18)
这基本上不是很复杂,但有一些检查可以避免毛刺。
var $poped = $('someselector');
// Trigger for the popover
$poped.each(function() {
var $this = $(this);
$this.on('hover',function() {
var popover = $this.data('popover');
var shown = popover && popover.tip().is(':visible');
if(shown) return; // Avoids flashing
$this.popover('show');
});
});
// Trigger for the hiding
$('html').on('click.popover.data-api',function() {
$poped.popover('hide');
});
答案 5 :(得分:15)
所谓的高投票解决方案都没有正确地为我服务。 在第一次打开和关闭(通过点击其他元素)弹出窗口时,每个都会导致错误,它不会再次打开,直到您对触发链接进行两次点击一个。
所以我稍微修改了一下:
$(document).on('click', function (e) {
var
$popover,
$target = $(e.target);
//do nothing if there was a click on popover content
if ($target.hasClass('popover') || $target.closest('.popover').length) {
return;
}
$('[data-toggle="popover"]').each(function () {
$popover = $(this);
if (!$popover.is(e.target) &&
$popover.has(e.target).length === 0 &&
$('.popover').has(e.target).length === 0)
{
$popover.popover('hide');
} else {
//fixes issue described above
$popover.popover('toggle');
}
});
})
答案 6 :(得分:11)
我做了一个jsfiddle来告诉你如何做到这一点:
想法是在单击按钮时显示弹出框,并在单击按钮外时隐藏弹出窗口。
<a id="button" href="#" class="btn btn-danger">Click for popover</a>
$('#button').popover({
trigger: 'manual',
position: 'bottom',
title: 'Example',
content: 'Popover example for SO'
}).click(function(evt) {
evt.stopPropagation();
$(this).popover('show');
});
$('html').click(function() {
$('#button').popover('hide');
});
答案 7 :(得分:3)
here之前已经提到过这个问题。我给出的答案仍然适用:
我有类似的需求,发现了这个great little extension of the Twitter Bootstrap Popover by Lee Carmichael, called BootstrapX - clickover。他还有一些使用示例here。基本上它会将popover更改为一个交互式组件,当您单击页面上的其他位置或弹出窗口中的关闭按钮时,该组件将关闭。这也将允许一次打开多个弹出窗口以及一堆其他不错的功能。
答案 8 :(得分:3)
修改了已接受的解决方案我所经历的是,在隐藏了一些弹出窗口之后,必须再次点击它们才能再次出现。这就是我所做的,以确保在已经隐藏的popovers上调用popover(&#39; hide&#39;)。
$('body').on('click', function (e) {
$('[data-original-title]').each(function () {
//the 'is' for buttons that trigger popups
//the 'has' for icons within a button that triggers a popup
if (!$(this).is(e.target) && $(this).has(e.target).length === 0 && $('.popover').has(e.target).length === 0) {
var popoverElement = $(this).data('bs.popover').tip();
var popoverWasVisible = popoverElement.is(':visible');
if (popoverWasVisible) {
$(this).popover('hide');
$(this).click(); // double clicking required to reshow the popover if it was open, so perform one click now
}
}
});
});
答案 9 :(得分:3)
派对迟到了......但我想我会分享它。 我喜欢popover但它的内置功能很少。我写了一个bootstrap扩展名.bubble(),这就是我想要的东西。四种解雇方式。单击“外部”,在链接上切换,单击X,然后单击“转义”。
它会自动定位,因此它永远不会离开页面。
https://github.com/Itumac/bootstrap-bubble
这不是一个无偿的自我宣传...我生命中已经多次抓住别人的代码,我想提供自己的努力。给它一个旋转,看看它是否适合你。
答案 10 :(得分:3)
只需使用元素
添加此属性即可data-trigger="focus"
答案 11 :(得分:3)
根据http://getbootstrap.com/javascript/#popovers,
<button type="button" class="popover-dismiss" data-toggle="popover" title="Dismissible popover" data-content="Popover Content">Dismissible popover</button>
使用焦点触发器消除用户下次点击时的弹出窗口。
$('.popover-dismiss').popover({
trigger: 'focus'
})
答案 12 :(得分:2)
Bootstrap natively supports this:
解雇下一次点击所需的特定标记
要获得正确的跨浏览器和跨平台行为,您必须使用
<a>
标记,不<button>
标记,并且还必须包含{{1 }和role="button"
属性。
答案 13 :(得分:2)
这个解决方案在第二次显示弹出窗口时摆脱了令人讨厌的第二次点击
使用Bootstrap v3.3.7进行测试
$('body').on('click', function (e) {
$('.popover').each(function () {
var popover = $(this).data('bs.popover');
if (!popover.$element.is(e.target)) {
popover.inState.click = false;
popover.hide();
}
});
});
答案 14 :(得分:2)
我们发现@mattdlockyer的解决方案存在问题(感谢解决方案!)。当像这样使用popover构造函数的selector属性时......
$(document.body').popover({selector: '[data-toggle=popover]'});
......建议的BS3解决方案不会起作用。相反,它会在其$(this)
本地创建第二个弹出框实例。以下是我们的解决方案:
$(document.body).on('click', function (e) {
$('[data-toggle="popover"]').each(function () {
//the 'is' for buttons that trigger popups
//the 'has' for icons within a button that triggers a popup
if (!$(this).is(e.target) && $(this).has(e.target).length === 0 && $('.popover').has(e.target).length === 0) {
var bsPopover = $(this).data('bs.popover'); // Here's where the magic happens
if (bsPopover) bsPopover.hide();
}
});
});
如上所述,由于委托的侦听器,$(this).popover('hide');
将创建第二个实例。提供的解决方案只隐藏已经实现的popovers。
我希望我能节省你们一些时间。
答案 15 :(得分:2)
似乎隐藏了&#39;如果您使用选择器委派创建弹出窗口,而不是&#39; destroy&#39;必须使用。
我让它像那样工作:
$('body').popover({
selector: '[data-toggle="popover"]'
});
$('body').on('click', function (e) {
$('[data-toggle="popover"]').each(function () {
//the 'is' for buttons that trigger popups
//the 'has' for icons within a button that triggers a popup
if (!$(this).is(e.target) && $(this).has(e.target).length === 0 && $('.popover').has(e.target).length === 0) {
$(this).popover('destroy');
}
});
});
答案 16 :(得分:2)
您还可以使用事件冒泡来从DOM中删除弹出窗口。它有点脏,但工作正常。
$('body').on('click touchstart', '.popover-close', function(e) {
return $(this).parents('.popover').remove();
});
在你的html中,将.popover-close类添加到应该关闭popover的popover中的内容。
答案 17 :(得分:2)
jQuery("#menu").click(function(){ return false; });
jQuery(document).one("click", function() { jQuery("#menu").fadeOut(); });
答案 18 :(得分:1)
我已经尝试了许多以前的答案,对我来说真的没什么用,但是这个解决方案确实如此:
https://getbootstrap.com/docs/3.3/javascript/#dismiss-on-next-click
他们建议使用锚标记而不是按钮,并注意角色=“按钮”+ data-trigger =“focus”+ tabindex =“0”属性。
例如:
<a tabindex="0" class="btn btn-lg btn-danger" role="button" data-toggle="popover"
data-trigger="focus" title="Dismissible popover" data-content="amazing content">
Dismissible popover</a>
答案 19 :(得分:1)
我只是在显示新的弹出窗口(bootstrap 3)之前删除其他活动的弹出窗口:
$(".my-popover").popover();
$(".my-popover").on('show.bs.popover',function () {
$('.popover.in').remove();
});
答案 20 :(得分:1)
此解决方案效果很好:
$("body") .on('click' ,'[data-toggle="popover"]', function(e) {
e.stopPropagation();
});
$("body") .on('click' ,'.popover' , function(e) {
e.stopPropagation();
});
$("body") .on('click' , function(e) {
$('[data-toggle="popover"]').popover('hide');
});
答案 21 :(得分:1)
用3.3.6测试,第二次点击就可以了
$('[data-toggle="popover"]').popover()
.click(function () {
$(this).popover('toggle');
});;
$(document).on('click', function (e) {
$('[data-toggle="popover"]').each(function () {
//the 'is' for buttons that trigger popups
//the 'has' for icons within a button that triggers a popup
if (!$(this).is(e.target) && $(this).has(e.target).length === 0 && $('.popover').has(e.target).length === 0) {
$(this).popover('hide');
}
});
});
答案 22 :(得分:0)
我找到了解决此问题的简便方法。 这样,只有在需要时才激活事件监听器。 此外,我们不会出现弹出窗口的问题,因为 撤消弹出窗口的事件时会同时触发。
将弹出窗口添加到HTML
<input id="popoverId" type="text" data-toggle="popover" data-trigger="manual" data-content="Popover content">
根据需要显示弹出窗口。
$('#popoverId').popover('show');
将此侦听器添加到您的Javascript。弹出窗口显示后,此监听器将立即触发 并将侦听器附加到身体上,这将隐藏 当用户单击页面正文中的任意位置,然后删除事件侦听器,直到再次显示弹出窗口时,弹出窗口。
$('#popoverId').on('shown.bs.popover', function () {
$('body').click(function () {
$('#popoverId').popover('hide');
$('body').off();
});
});
答案 23 :(得分:0)
只需将此属性添加到html元素即可在下次点击时关闭popover。
data-trigger="focus"
的参考资料
答案 24 :(得分:0)
只需设置 data-trigger =“焦点点击”
答案 25 :(得分:0)
接受答案的最新更新存在问题: 如果您启用了一些工具提示并打开弹出窗口然后单击工具提示元素,则工具提示的文本将显示为弹出窗口。
要防止这种情况,只需添加
即可 if ($(this).data('bs.popover')) {
在if语句中使用(或者将它与&amp;&amp;和@语句连接起来)
// only show one popover at the time and hide on clicking outside
$(document).on('click', function (e) {
$('[data-toggle="popover"],[data-original-title]').each(function () {
//the 'is' for buttons that trigger popups
//the 'has' for icons within a button that triggers a popup
if (!$(this).is(e.target) && $(this).has(e.target).length === 0 && $('.popover').has(e.target).length === 0) {
if ($(this).data('bs.popover')) {
(($(this).popover('hide').data('bs.popover') || {}).inState || {}).click = false // fix for BS 3.3.6
}
}
});
});
答案 26 :(得分:0)
.indx-BG {
background: url('../img/<?php echo $image_for_today ?>.jpg') no-repeat center center;
}
答案 27 :(得分:0)
根据最高的两个答案,我有一个小解决方案:
<span class="btn btn-info btn-minier popover-info" data-rel="popover"
data-placement="bottom" data-html="true" title=""
data-content="popover-content"
data-original-title="popover-title">
<i class="ace-icon fa fa-info smaller-100"></i>
</span>
$('[data-rel=popover]').popover({html: true});
$(document).on("shown.bs.popover", '[data-rel=popover]', function () {
$('[data-rel="popover"][popover-show="1"]').popover('hide');
$(this).attr('popover-show', '1');
});
$(document).on("hidden.bs.popover", '[data-rel=popover]', function () {
if ($(this).attr('popover-show') === '0') {
// My important fix: using bootstrap 3.4.1, if hide popover by .popover('hide') and click to show, popover internal treat it is already shown and dispatch hidden event immediately without popover anything.
$(this).popover('toggle');
} else {
$(this).attr('popover-show', '0');
}
});
$('html').on('click', function (e) {
if (typeof $(e.target).data('original-title') == 'undefined'
&& typeof $(e.target).parent().data('original-title') == 'undefined'
&& !$(e.target).parents().is('.popover.in')) {
$('[data-rel="popover"][popover-show="1"]').popover('hide');
}
});
答案 28 :(得分:0)
对于正在寻找适用于 Bootstrap 5 而没有 jQuery 的解决方案的任何人,即使弹出窗口是动态生成的(即手动触发):
document.querySelector('body').addEventListener('click', function(e) {
var in_popover = e.target.closest(".popover");
if (!in_popover) {
var popovers = document.querySelectorAll('.popover.show');
if (popovers[0]) {
var triggler_selector = `[aria-describedby=${popovers[0].id}]`;
if (!e.target.closest(triggler_selector)) {
let the_trigger = document.querySelector(triggler_selector);
if (the_trigger) {
bootstrap.Popover.getInstance(the_trigger).hide();
}
}
}
}
});
答案 29 :(得分:0)
答案非常有效,只是为了添加一个角度指令,以防你像我一样使用角度:
app.directive('popover', ['$document', function($document) {
return {
restrict: 'EA',
link: function(scope, elem, attrs) {
$(document).ready(function() {
$('[data-toggle="popover"]').popover();
});
elem.bind('click', function(e) {
$('#notification').popover('toggle');
})
$('body').on('click', function (e) {
//the 'is' for buttons that trigger popups
//the 'has' for icons within a button that triggers a popup
if (!elem.is(e.target)
&& elem.has(e.target).length === 0
&& $('.popover').has(e.target).length === 0) {
elem.popover('hide');
}
});
}
};
}]);
html代码:
<a popover tabindex="0" role="button"
id="notification"
data-toggle="popover" data-trigger="manual"
data-container="body" data-placement="bottom"
data-content="This is a popover">
Popover button
</a>
它应该像使用data-trigger='click focus'
一样简单,因为根据bootstrap:
如何触发弹出窗口 - 单击|悬停|焦点|手册。你可以传递多个触发器;用空格隔开它们。手册不能与任何其他触发器结合使用。
然而,使用点击和聚焦在一起对我来说不明原因,我必须手动切换它。
答案 30 :(得分:0)
$('html').on('click.popover', function (e) {
var allpopins = $('.popover.in');
if (allpopins.has(e.target).length > 0 &&
!$('.btn', allpopins).is(e.target))
return;
// recognise pop-up
var id = $(e.target).attr('aria-describedby');
var popin = $("#" + id);
//on any button click in entire pop-up hide this pop-ups
$(popin).on(".btn", function () { popin.remove(); });
// on any place out of entire popup hide all pop-ups
$('.popover.in').not(popin).remove();
});
这是我最好的性能解决方案。欢呼声。
答案 31 :(得分:0)
@guya的答案有效,除非你在popover中有类似日期选择器或时间戳的东西。为了解决这个问题,我就是这样做的。
if (typeof $(e.target).data('original-title') === 'undefined' &&
!$(e.target).parents().is('.popover.in')) {
var x = $(this).parents().context;
if(!$(x).hasClass("datepicker") && !$(x).hasClass("ui-timepicker-wrapper")){
$('[data-original-title]').popover('hide');
}
}
答案 32 :(得分:0)
我遇到了mattdlockyer解决方案的问题,因为我使用这样的代码动态设置popover链接:
$('body').popover({
selector : '[rel="popover"]'
});
所以我必须像这样修改它。它为我解决了很多问题:
$('html').on('click', function (e) {
$('[data-toggle="popover"]').each(function () {
//the 'is' for buttons that trigger popups
//the 'has' for icons within a button that triggers a popup
if (!$(this).is(e.target) && $(this).has(e.target).length === 0 && $('.popover').has(e.target).length === 0) {
$(this).popover('destroy');
}
});
});
请记住,destroy会删除元素,因此选择器部分对于初始化弹出窗口非常重要。
答案 33 :(得分:0)
试试这个,点击外面会隐藏。
$('body').on('click', function (e) {
$('[data-toggle="popover"]').each(function () {
//the 'is' for buttons that trigger popups
//the 'has' for icons within a button that triggers a popup
if (!$(this).is(e.target) && $(this).has(e.target).length === 0 && $('.popover').has(e.target).length === 0) {
$(this).popover('hide');
}
});
});
答案 34 :(得分:0)
采用Matt Lockyer的代码,我做了一个简单的重置,因此dom不会被hide上的元素覆盖。
马特的代码:http://mattlockyer.com/2013/04/08/close-a-twitter-bootstrap-popover-when-clicking-outside/
小提琴:http://jsfiddle.net/mrsmith/Wd2qS/
$('body').on('click', function (e) {
//hide popover from dom to prevent covering elements
$('.popover').css('display', 'none');
//bring popover back if trigger element is clicked
$('[data-toggle="popover"]').each(function () {
if ($(this).is(e.target) && $(this).has(e.target).length === 0 && $('.popover').has(e.target).length === 0) {
$('.popover').css('display', 'block');
}
});
//hide popover with .popover method
$('[data-toggle="popover"]').each(function () {
//the 'is' for buttons that trigger popups
//the 'has' for icons within a button that triggers a popup
if (!$(this).is(e.target) && $(this).has(e.target).length === 0 && $('.popover').has(e.target).length === 0) {
$(this).popover('hide');
}
});
});
答案 35 :(得分:0)
我想出了这个: 我的场景在同一页面上包含更多弹出窗口,隐藏它们只是让它们不可见,因此,单击弹出窗口后面的项目是不可能的。 我们的想法是将特定的popover-link标记为“active”,然后您可以简单地“切换”活动的popover。这样做会完全关闭弹出窗口 $('。popover-link')。popover({html:true,container:'body'})
$('.popover-link').popover().on 'shown.bs.popover', ->
$(this).addClass('toggled')
$('.popover-link').popover().on 'hidden.bs.popover', ->
$(this).removeClass('toggled')
$("body").on "click", (e) ->
$openedPopoverLink = $(".popover-link.toggled")
if $openedPopoverLink.has(e.target).length == 0
$openedPopoverLink.popover "toggle"
$openedPopoverLink.removeClass "toggled"
答案 36 :(得分:0)
好的,这是我第一次尝试在stackoverflow上回答一些事情,所以这里什么都没有:P
似乎不太清楚这个功能实际上是否在最新的引导程序中开箱即用(好吧,如果你愿意妥协用户可以点击的。我我不确定你是否必须在iPad上点击“点击悬停”,但点击作为一个切换点。
最终结果是,在桌面上您可以悬停或点击(大多数用户将悬停)。在触摸设备上,触摸元素会将其抬起,再次触摸它会将其取下。当然,这与您原来的要求略有不同,但至少您的代码现在更清晰:)
$( “我-酥料饼”)。酥料饼({ 触发器:'click hover' });
答案 37 :(得分:0)
此方法可确保您可以通过单击页面上的任意位置来关闭弹出窗口。如果单击另一个可单击的实体,它将隐藏所有其他弹出窗口。动画:false是必需的,否则你的控制台会出现jquery .remove错误。
$('.clickable').popover({
trigger: 'manual',
animation: false
}).click (evt) ->
$('.clickable').popover('hide')
evt.stopPropagation()
$(this).popover('show')
$('html').on 'click', (evt) ->
$('.clickable').popover('hide')
答案 38 :(得分:0)
演示:http://jsfiddle.net/nessajtr/yxpM5/1/
var clickOver = clickOver || {};
clickOver.uniqueId = $.now();
clickOver.ClickOver = function (selector, options) {
var self = this;
//default values
var isVisible, clickedAway = false;
var callbackMethod = options.content;
var uniqueDiv = document.createElement("div");
var divId = uniqueDiv.id = ++clickOver.uniqueId;
uniqueDiv.innerHTML = options.loadingContent();
options.trigger = 'manual';
options.animation = false;
options.content = uniqueDiv;
self.onClose = function () {
$("#" + divId).html(options.loadingContent());
$(selector).popover('hide')
isVisible = clickedAway = false;
};
self.onCallback = function (result) {
$("#" + divId).html(result);
};
$(selector).popover(options);
//events
$(selector).bind("click", function (e) {
$(selector).filter(function (f) {
return $(selector)[f] != e.target;
}).popover('hide');
$(selector).popover("show");
callbackMethod(self.onCallback);
isVisible = !(clickedAway = false);
});
$(document).bind("click", function (e) {
if (isVisible && clickedAway && $(e.target).parents(".popover").length == 0) {
self.onClose();
isVisible = clickedAway = false;
} else clickedAway = true;
});
}
这是我的解决方案。
答案 39 :(得分:-2)
$("body").find('.popover').removeClass('in');
答案 40 :(得分:-2)
这么简单,只需添加:
$('body').on('click', function() {
$('.popover').each(function() {
$(this).popover('hide');
});
});