我们可以使弹出窗口与模式一样被消除吗?当用户单击它们外部的某个位置时使它们关闭?
不幸的是,我不能只使用真实的模式而不是popover,因为modal意味着position:fixed,这将不再是popover。:(
data-trigger="hover"
并且data-trigger="focus"
是您不想使用切换功能时关闭弹出窗口的内置替代方法。在我看来,data-trigger="hover"
它提供了最佳的用户体验...无需编写额外的.js代码...
我们可以使弹出窗口与模式一样被消除吗?当用户单击它们外部的某个位置时使它们关闭?
不幸的是,我不能只使用真实的模式而不是popover,因为modal意味着position:fixed,这将不再是popover。:(
data-trigger="hover"
并且data-trigger="focus"
是您不想使用切换功能时关闭弹出窗口的内置替代方法。在我看来,data-trigger="hover"
它提供了最佳的用户体验...无需编写额外的.js代码...
Answers:
更新:更为健壮的解决方案: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生成Popovers使用'[data-original-title]'
代替'[data-toggle="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,请参见小提琴
修复了关闭后需要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
}
});
});
更新:使用之前的改进作为前提,此解决方案得以实现。解决了双击和幻影弹出窗口的问题:
$(document).on("shown.bs.popover",'[data-toggle="popover"]', function(){
$(this).attr('someattr','1');
});
$(document).on("hidden.bs.popover",'[data-toggle="popover"]', function(){
$(this).attr('someattr','0');
});
$(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).attr('someattr')=="1"){
$(this).popover("toggle");
}
}
});
});
$(document)
而不是$('body')
因为有时它们body
不会延伸到整个页面。
'[data-toggle="popover"]'
,它不能用于JavaScript生成的弹出窗口,而是用作'[data-original-title]'
选择器。
$('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");
});
}
});
最简单,最安全的故障版本,可与任何引导程序版本一起使用。
演示: http //jsfiddle.net/guya/24mmM/
演示2:在弹出窗口内容内单击时不关闭 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');
}
});
上面的代码段在主体上附加了click事件。当用户单击弹出窗口时,它的行为将正常。当用户单击不是弹出窗口的内容时,它将关闭所有弹出窗口。
与其他无法使用的示例相反,它也可以使用以Javascript启动的弹出窗口。(请参见演示)
如果您不希望在单击弹出窗口内容时退出,请使用以下代码(请参阅第二个演示的链接):
$('html').on('click', function(e) {
if (typeof $(e.target).data('original-title') == 'undefined' && !$(e.target).parents().is('.popover.in')) {
$('[data-original-title]').popover('hide');
}
});
!$(e.target).closest('.popover.in').length
会比效率更高!$(e.target).parents().is('.popover.in')
。
使用bootstrap 2.3.2,您可以将触发器设置为“ focus”,并且它可以正常工作:
$('#el').popover({trigger:'focus'});
这基本上不是很复杂,但是需要做一些检查以避免毛刺。
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');
});
popover()
通过单击而不是悬停来执行此操作?
stopPropagation()
传递给click处理程序的事件(如果不是,则隐藏处理程序立即隐藏弹出窗口)。演示(jsfiddle)
假定的投票解决方案都无法正确地为我工作。每次打开和关闭(通过单击其他元素)弹出框后,每个都导致一个错误,直到您创建两个弹出框后,它才会再次打开在触发链接上单击而不是单击。
所以我做了一点修改:
$(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');
}
});
})
我做了一个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');
});
jsfiddle bootstrap
它给了我jsfiddle中bootstrap css + js的框架。
这里已经问过了。我给出的相同答案仍然适用:
我也有类似的需求,并发现Lee Carmichael的Twitter Bootstrap Popover的这个小扩展名叫做BootstrapX-clickover。他在这里也有一些用法示例。基本上,它将弹出窗口更改为交互式组件,当您单击页面上的其他位置或弹出窗口中的关闭按钮时,该组件将关闭。这也将允许一次打开多个弹出窗口以及许多其他不错的功能。
晚会晚了……但我想我愿意分享。我喜欢Popover,但内置功能很少。我写了一个bootstrap扩展名.bubble(),它就是我想要的popover。四种解雇方式。单击外部,切换链接,单击X,然后按Escape键。
它会自动定位,因此永远不会离开页面。
https://github.com/Itumac/bootstrap-bubble
这不是一个无谓的自我推广……我一生中已经抓了很多遍别人的代码,我想提供自己的努力。旋转一下,看看它是否对您有用。
根据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'
})
<a>
标签,而不是<button>
标签,并且还必须包含role="button"
和tabindex
属性。” 您是否尝试过这些规格?
修改后的接受解决方案。我所经历的是,在隐藏了一些弹出窗口之后,必须单击两次才能再次显示它们。这是我要确保不会在已经隐藏的弹出窗口上调用popover('hide')的操作。
$('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
}
}
});
});
只需将此属性添加到html元素即可在下次单击中关闭弹出窗口。
data-trigger="focus"
如果您使用选择器委托创建弹出窗口,似乎“隐藏”方法不起作用,而必须使用“销毁”。
我使它像这样工作:
$('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');
}
});
});
我们发现@mattdlockyer的解决方案存在问题(感谢解决方案!)。当使用popper构造函数的选择器属性时,像这样...
$(document.body').popover({selector: '[data-toggle=popover]'});
...针对BS3提出的解决方案将不起作用。而是在其本地创建第二个popover实例$(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');
由于委托了侦听器,因此将创建第二个实例。提供的解决方案仅隐藏已实例化的弹出窗口。
我希望我可以节省你们一些时间。
Bootstrap 本机支持:
下次单击时需要关闭的特定标记
对于正确的跨浏览器和跨平台的行为,则必须使用
<a>
标签,不是的<button>
标签,你还必须包括role="button"
和tabindex
属性。
我已经尝试了许多以前的答案,但实际上对我没有任何帮助,但是此解决方案可以做到:
https://getbootstrap.com/docs/3.3/javascript/#dismiss-on-next-click
他们建议使用锚标记而不是按钮,并注意role =“ button” + 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>
我想到了这一点:我的方案在同一页面上包含更多弹出窗口,并且将它们隐藏起来只是使其不可见,因此,无法单击弹出窗口后面的项目。这个想法是将特定的popover链接标记为“活动”,然后您可以简单地“切换”活动的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"
用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');
}
});
});
演示: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;
});
}
这是我的解决方案。
这种方法可确保您可以通过单击页面上的任意位置来关闭弹出窗口。如果单击另一个可单击的实体,它将隐藏所有其他弹出框。animation: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')
以马特·洛克耶(Matt Lockyer)的代码为例,我进行了一次简单的重置,以使dom不会被hide上的元素覆盖。
马特(Matt)的代码: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');
}
});
});
尝试此操作,将其隐藏在外部。
$('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');
}
});
});
我在使用mattdlockyer的解决方案时遇到了问题,因为我正在使用如下代码动态设置弹出链接:
$('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摆脱了元素,因此选择器部分对于初始化弹出窗口很重要。