我目前正在使用Twitter Bootstrap的popovers,就像这样发起:
$('.popup-marker').popover({
html: true,
trigger: 'manual'
}).click(function(e) {
$(this).popover('toggle');
e.preventDefault();
});
如您所见,它们是手动触发的,然后单击.popup-marker(带有背景图像的div)切换弹出框。这很好用,但我也希望能够通过点击页面上任何其他位置来关闭popover(但不能在popover本身!)。
我尝试了一些不同的东西,包括以下内容,但没有显示结果:
$('body').click(function(e) {
$('.popup-marker').popover('hide');
});
如何通过点击页面上的任何其他位置来关闭弹出窗口,但是不能单击弹出窗口本身?
答案 0 :(得分:99)
假设任何时候只能看到一个弹出框,你可以使用一组标记来标记弹出窗口何时可见,然后才隐藏它们。
如果在文档正文中设置事件侦听器,则在单击标有“popup-marker”的元素时会触发该事件侦听器。因此,您必须在事件对象上调用stopPropagation()
。点击弹出窗口时应用相同的技巧。
下面是一个可以执行此操作的JavaScript代码。它使用jQuery> = 1.7
jQuery(function() {
var isVisible = false;
var hideAllPopovers = function() {
$('.popup-marker').each(function() {
$(this).popover('hide');
});
};
$('.popup-marker').popover({
html: true,
trigger: 'manual'
}).on('click', function(e) {
// if any other popovers are visible, hide them
if(isVisible) {
hideAllPopovers();
}
$(this).popover('show');
// handle clicking on the popover itself
$('.popover').off('click').on('click', function(e) {
e.stopPropagation(); // prevent event for bubbling up => will not get caught with document.onclick
});
isVisible = true;
e.stopPropagation();
});
$(document).on('click', function(e) {
hideAllPopovers();
isVisible = false;
});
});
http://jsfiddle.net/AFffL/539/
唯一需要注意的是,您无法同时打开2个弹出式窗口。但我觉得这对用户来说会让人感到困惑: - )
答案 1 :(得分:73)
这更容易:
$('html').click(function(e) {
$('.popup-marker').popover('hide');
});
$('.popup-marker').popover({
html: true,
trigger: 'manual'
}).click(function(e) {
$(this).popover('toggle');
e.stopPropagation();
});
答案 2 :(得分:48)
我有类似的需求,发现了这个great little extension of the Twitter Bootstrap Popover by Lee Carmichael, called BootstrapX - clickover。他还有一些使用示例here。基本上它会将popover更改为一个交互式组件,当您单击页面上的其他位置或弹出窗口中的关闭按钮时,该组件将关闭。这也将允许一次打开多个弹出窗口以及一堆其他不错的功能。
用法示例
<button rel="clickover" data-content="Show something here.
<button data-dismiss='clickover'
>Close Clickover</button>"
>Show clickover</button>
javascript:
// load click overs using 'rel' attribute
$('[rel="clickover"]').clickover();
答案 3 :(得分:37)
接受的解决方案给了我一些问题(点击打开的popover的'.popup-marker'元素使得popovers随后不起作用)。我想出了另一个适合我的解决方案,它非常简单(我正在使用Bootstrap 2.3.1):
$('.popup-marker').popover({
html: true,
trigger: 'manual'
}).click(function(e) {
$('.popup-marker').not(this).popover('hide');
$(this).popover('toggle');
});
$(document).click(function(e) {
if (!$(e.target).is('.popup-marker, .popover-title, .popover-content')) {
$('.popup-marker').popover('hide');
}
});
更新:此代码也适用于Bootstrap 3!
答案 4 :(得分:19)
阅读“下次点击后关闭” 这里http://getbootstrap.com/javascript/#popovers
您可以使用焦点触发器在下次点击时关闭弹出窗口,但您必须使用<a>
标记,而不是<button>
标记,并且还必须包含{{1} }属性...
示例:
tabindex
答案 5 :(得分:7)
所有现有答案都相当薄弱,因为它们依赖于捕获所有文档事件,然后查找活动弹出框,或修改对.popover()
的调用。
更好的方法是在文档的主体上侦听show.bs.popover
事件,然后做出相应的反应。下面是单击文档或按下 esc 时将关闭弹出窗口的代码,当显示弹出窗口时仅绑定事件侦听器:
function closePopoversOnDocumentEvents() {
var visiblePopovers = [];
var $body = $("body");
function hideVisiblePopovers() {
$.each(visiblePopovers, function() {
$(this).popover("hide");
});
}
function onBodyClick(event) {
if (event.isDefaultPrevented())
return;
var $target = $(event.target);
if ($target.data("bs.popover"))
return;
if ($target.parents(".popover").length)
return;
hideVisiblePopovers();
}
function onBodyKeyup(event) {
if (event.isDefaultPrevented())
return;
if (event.keyCode != 27) // esc
return;
hideVisiblePopovers();
event.preventDefault();
}
function onPopoverShow(event) {
if (!visiblePopovers.length) {
$body.on("click", onBodyClick);
$body.on("keyup", onBodyKeyup);
}
visiblePopovers.push(event.target);
}
function onPopoverHide(event) {
var target = event.target;
var index = visiblePopovers.indexOf(target);
if (index > -1) {
visiblePopovers.splice(index, 1);
}
if (visiblePopovers.length == 0) {
$body.off("click", onBodyClick);
$body.off("keyup", onBodyKeyup);
}
}
$body.on("show.bs.popover", onPopoverShow);
$body.on("hide.bs.popover", onPopoverHide);
}
答案 6 :(得分:5)
https://github.com/lecar-red/bootstrapx-clickover
它是twitter bootstrap popover的扩展,可以非常简单地解决问题。
答案 7 :(得分:2)
即使这里有很多解决方案,我也想提出我的解决方案,我不知道是否有一些解决方案可以解决这一切,但我尝试了其中3个并且他们遇到了问题,就像点击popover它自己让它隐藏,其他如果我有另外的popover按钮点击两个/多个popover仍然会出现(如在选定的解决方案中),但是,这一个修复了所有
var curr_popover_btn = null;
// Hide popovers function
function hide_popovers(e)
{
var container = $(".popover.in");
if (!container.is(e.target) // if the target of the click isn't the container...
&& container.has(e.target).length === 0) // ... nor a descendant of the container
{
if( curr_popover_btn != null )
{
$(curr_popover_btn).popover('hide');
curr_popover_btn = null;
}
container.hide();
}
}
// Hide popovers when out of focus
$('html').click(function(e) {
hide_popovers(e);
});
$('.popover-marker').popover({
trigger: 'manual'
}).click(function(e) {
hide_popovers(e);
var $popover_btns = $('.popover-marker');
curr_popover_btn = this;
var $other_popover_btns = jQuery.grep($($popover_btns), function(popover_btn){
return ( popover_btn !== curr_popover_btn );
});
$($other_popover_btns).popover('hide');
$(this).popover('toggle');
e.stopPropagation();
});
答案 8 :(得分:2)
出于某种原因,这里没有其他解决方案适用于我。然而,经过大量的故障排除后,我终于找到了这种方法,它完美地起作用(至少对我而言)。
$('html').click(function(e) {
if( !$(e.target).parents().hasClass('popover') ) {
$('#popover_parent').popover('destroy');
}
});
在我的情况下,我在表格中添加了一个弹出窗口,并将其绝对定位在单击的td
上方/下方。表选择由jQuery-UI Selectable处理,所以我不确定这是否干扰。但是,每当我在popover中单击时,我的单击处理程序($('.popover')
)从未起作用,并且事件处理始终委托给$(html)
单击处理程序。我对JS很新,所以也许我只是错过了什么?
无论如何,我希望这有助于某人!
答案 9 :(得分:2)
我给所有的弹出窗口锚定了班级activate_popover
。我马上激活它们
$('body').popover({selector: '.activate-popover', html : true, container: 'body'})
让我使用的点击离开功能(在咖啡脚本中):
$(document).on('click', (e) ->
clickedOnActivate = ($(e.target).parents().hasClass("activate-popover") || $(e.target).hasClass("activate-popover"))
clickedAway = !($(e.target).parents().hasClass("popover") || $(e.target).hasClass("popover"))
if clickedAway && !clickedOnActivate
$(".popover.in").prev().popover('hide')
if clickedOnActivate
$(".popover.in").prev().each () ->
if !$(this).is($(e.target).closest('.activate-popover'))
$(this).popover('hide')
)
使用bootstrap 2.3.1
完全正常答案 10 :(得分:1)
稍微调整了@David Wolever解决方案:
function closePopoversOnDocumentEvents() {
var visiblePopovers = [];
var $body = $("body");
function hideVisiblePopovers() {
/* this was giving problems and had a bit of overhead
$.each(visiblePopovers, function() {
$(this).popover("hide");
});
*/
while (visiblePopovers.length !== 0) {
$(visiblePopovers.pop()).popover("hide");
}
}
function onBodyClick(event) {
if (event.isDefaultPrevented())
return;
var $target = $(event.target);
if ($target.data("bs.popover"))
return;
if ($target.parents(".popover").length)
return;
hideVisiblePopovers();
}
function onBodyKeyup(event) {
if (event.isDefaultPrevented())
return;
if (event.keyCode != 27) // esc
return;
hideVisiblePopovers();
event.preventDefault();
}
function onPopoverShow(event) {
if (!visiblePopovers.length) {
$body.on("click", onBodyClick);
$body.on("keyup", onBodyKeyup);
}
visiblePopovers.push(event.target);
}
function onPopoverHide(event) {
var target = event.target;
var index = visiblePopovers.indexOf(target);
if (index > -1) {
visiblePopovers.splice(index, 1);
}
if (visiblePopovers.length == 0) {
$body.off("click", onBodyClick);
$body.off("keyup", onBodyKeyup);
}
}
$body.on("show.bs.popover", onPopoverShow);
$body.on("hide.bs.popover", onPopoverHide);
}
答案 11 :(得分:1)
我在使用bootstrap 2.3.2时遇到了一些问题。 但我这样解决了:
$(function () {
$(document).mouseup(function (e) {
if(($('.popover').length > 0) && !$(e.target).hasClass('popInfo')) {
$('.popover').each(function(){
$(this).prev('.popInfo').popover('hide');
});
}
});
$('.popInfo').popover({
trigger: 'click',
html: true
});
});
答案 12 :(得分:1)
我会将焦点设置为新创建的弹出窗口并在模糊时将其移除。这样就不需要检查DOM的哪个元素被点击,并且可以点击弹出窗口,也可以选择它:它不会失去焦点而不会消失。
代码:
$('.popup-marker').popover({
html: true,
trigger: 'manual'
}).click(function(e) {
$(this).popover('toggle');
// set the focus on the popover itself
jQuery(".popover").attr("tabindex",-1).focus();
e.preventDefault();
});
// live event, will delete the popover by clicking any part of the page
$('body').on('blur','.popover',function(){
$('.popup-marker').popover('hide');
});
答案 13 :(得分:1)
这是我的解决方案,值得:
// Listen for clicks or touches on the page
$("html").on("click.popover.data-api touchend.popover.data-api", function(e) {
// Loop through each popover on the page
$("[data-toggle=popover]").each(function() {
// Hide this popover if it's visible and if the user clicked outside of it
if ($(this).next('div.popover:visible').length && $(".popover").has(e.target).length === 0) {
$(this).popover("hide");
}
});
});
答案 14 :(得分:1)
此问题也在这里提出,我的回答不仅提供了一种理解jQuery DOM遍历方法的方法,还提供了两种方法来通过点击外部来处理弹出窗口的关闭。
一次打开多个弹出窗口或一次打开一个弹出窗口。
另外,这些小代码片段可以处理关闭包含图标的按钮!
答案 15 :(得分:1)
这个就像一个魅力,我用它。
单击时会打开弹出窗口,如果再次单击它将关闭,如果单击弹出窗口外,弹出窗口将关闭。
这也适用于超过1个popover。
function hideAllPopovers(){
$('[data-toggle="popover"]').each(function() {
if ($(this).data("showing") == "true"){
$(this).data("showing", "false");
$(this).popover('hide');
}
});
}
$('[data-toggle="popover"]').each(function() {
$(this).popover({
html: true,
trigger: 'manual'
}).click(function(e) {
if ($(this).data("showing") != "true"){
hideAllPopovers();
$(this).data("showing", "true");
$(this).popover('show');
}else{
hideAllPopovers();
}
e.stopPropagation();
});
});
$(document).click(function(e) {
hideAllPopovers();
});
答案 16 :(得分:1)
这个解决方案对我来说非常好,如果有帮助的话:
/**
* Add the equals method to the jquery objects
*/
$.fn.equals = function(compareTo) {
if (!compareTo || this.length !== compareTo.length) {
return false;
}
for (var i = 0; i < this.length; ++i) {
if (this[i] !== compareTo[i]) {
return false;
}
}
return true;
};
/**
* Activate popover message for all concerned fields
*/
var popoverOpened = null;
$(function() {
$('span.btn').popover();
$('span.btn').unbind("click");
$('span.btn').bind("click", function(e) {
e.stopPropagation();
if($(this).equals(popoverOpened)) return;
if(popoverOpened !== null) {
popoverOpened.popover("hide");
}
$(this).popover('show');
popoverOpened = $(this);
e.preventDefault();
});
$(document).click(function(e) {
if(popoverOpened !== null) {
popoverOpened.popover("hide");
popoverOpened = null;
}
});
});
答案 17 :(得分:1)
另一种解决方案,它涵盖了我单击弹出窗口的后代时遇到的问题:
$(document).mouseup(function (e) {
// The target is not popover or popover descendants
if (!$(".popover").is(e.target) && 0 === $(".popover").has(e.target).length) {
$("[data-toggle=popover]").popover('hide');
}
});
答案 18 :(得分:0)
我喜欢这个,简单而有效..
var openPopup;
$('[data-toggle="popover"]').on('click',function(){
if(openPopup){
$(openPopup).popover('hide');
}
openPopup=this;
});
答案 19 :(得分:0)
将btn-popover
类添加到打开弹出窗口的弹出框按钮/链接中。此代码将在其外部单击时关闭弹出窗口。
$('body').on('click', function(event) {
if (!$(event.target).closest('.btn-popover, .popover').length) {
$('.popover').popover('hide');
}
});
答案 20 :(得分: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"
答案 21 :(得分:0)
更简单的解决方案,只需遍历所有弹出式窗口,如果不是this
则隐藏。
$(document).on('click', '.popup-marker', function() {
$(this).popover('toggle')
})
$(document).bind('click touchstart', function(e) {
var target = $(e.target)[0];
$('.popup-marker').each(function () {
// hide any open popovers except for the one we've clicked
if (!$(this).is(target)) {
$(this).popover('hide');
}
});
});
答案 22 :(得分:0)
$('.popForm').popover();
$('.conteneurPopForm').on("click",".fermePopover",function(){
$(".popForm").trigger("click");
});
要清楚,只需触发弹出窗口
即可答案 23 :(得分:0)
这应该在Bootstrap 4中起作用:
$("#my-popover-trigger").popover({
template: '<div class="popover my-popover-content" role="tooltip"><div class="arrow"></div><div class="popover-body"></div></div>',
trigger: "manual"
})
$(document).click(function(e) {
if ($(e.target).closest($("#my-popover-trigger")).length > 0) {
$("#my-popover-trigger").popover("toggle")
} else if (!$(e.target).closest($(".my-popover-content")).length > 0) {
$("#my-popover-trigger").popover("hide")
}
})
说明:
答案 24 :(得分:0)
我试图为一个简单的问题做一个简单的解决方案。上面的帖子很好但是对于一个简单的问题来说很复杂。所以我做了一件简单的事情。刚刚添加了一个关闭按钮。它对我来说很完美。
$(".popover-link").click(function(){
$(".mypopover").hide();
$(this).parent().find(".mypopover").show();
})
$('.close').click(function(){
$(this).parents('.mypopover').css('display','none');
});
<div class="popover-content">
<i class="fa fa-times close"></i>
<h3 class="popover-title">Title here</h3>
your other content here
</div>
.popover-content {
position:relative;
}
.close {
position:absolute;
color:#CCC;
right:5px;
top:5px;
cursor:pointer;
}
答案 25 :(得分:0)
我发现这是上面提到的pbaron建议的修改解决方案,因为他的解决方案使用类'popup-marker'激活所有元素上的popover('hide')。但是,当你使用popover()代替数据内容时,正如我在下面所做的那样,html弹出窗口内的任何点击实际上都会激活popover('hide'),这会立即关闭窗口。下面的方法遍历每个.popup-marker元素,如果父元素与被点击的.popup-marker的id相关,则首先发现,如果是,则不隐藏它。所有其他div都隐藏了......
$(function(){
$('html').click(function(e) {
// this is my departure from pbaron's code above
// $('.popup-marker').popover('hide');
$('.popup-marker').each(function() {
if ($(e.target).parents().children('.popup-marker').attr('id')!=($(this).attr('id'))) {
$(this).popover('hide');
}
});
});
$('.popup-marker').popover({
html: true,
// this is where I'm setting the html for content from a nearby hidden div with id="html-"+clicked_div_id
content: function() { return $('#html-'+$(this).attr('id')).html(); },
trigger: 'manual'
}).click(function(e) {
$(this).popover('toggle');
e.stopPropagation();
});
});
答案 26 :(得分:0)
@RayOnAir,我对以前的解决方案有同样的问题。我也接近@RayOnAir解决方案。改进的一件事就是在点击其他popover标记时关闭已经打开的popover。所以我的代码是:
var clicked_popover_marker = null;
var popover_marker = '#pricing i';
$(popover_marker).popover({
html: true,
trigger: 'manual'
}).click(function (e) {
clicked_popover_marker = this;
$(popover_marker).not(clicked_popover_marker).popover('hide');
$(clicked_popover_marker).popover('toggle');
});
$(document).click(function (e) {
if (e.target != clicked_popover_marker) {
$(popover_marker).popover('hide');
clicked_popover_marker = null;
}
});
答案 27 :(得分:0)
如果您尝试使用pjax的twitter bootstrap popover,这对我有用:
App.Utils.Popover = {
enableAll: function() {
$('.pk-popover').popover(
{
trigger: 'click',
html : true,
container: 'body',
placement: 'right',
}
);
},
bindDocumentClickEvent: function(documentObj) {
$(documentObj).click(function(event) {
if( !$(event.target).hasClass('pk-popover') ) {
$('.pk-popover').popover('hide');
}
});
}
};
$(document).on('ready pjax:end', function() {
App.Utils.Popover.enableAll();
App.Utils.Popover.bindDocumentClickEvent(this);
});
答案 28 :(得分:0)
我按以下方式执行
$("a[rel=popover]").click(function(event){
if(event.which == 1)
{
$thisPopOver = $(this);
$thisPopOver.popover('toggle');
$thisPopOver.parent("li").click(function(event){
event.stopPropagation();
$("html").click(function(){
$thisPopOver.popover('hide');
});
});
}
});
希望这有帮助!
答案 29 :(得分:-1)
尝试使用data-trigger="focus"
代替"click"
。
这解决了我的问题。
答案 30 :(得分:-3)
jQuery(':not(.popup-marker)').once().click(function(){
jQuery('.popup-marker').hide();
});