如何在页面上的任何位置(其他位置)单击closuresTwitter Bootstrappopup窗口?

我目前正在使用Twitter Bootstrappopup,如下所示:

$('.popup-marker').popover({ html: true, trigger: 'manual' }).click(function(e) { $(this).popover('toggle'); e.preventDefault(); }); 

正如你所看到的,它们是手动触发的,然后点击.popup-marker(这是一个带有背景图片的div)来切换popover。 这很好,但我想也能够在页面上的任何地方点击closurespopup窗口(但不是popup窗口本身!)。

我已经尝试了几个不同的东西,包括以下内容,但没有结果显示:

 $('body').click(function(e) { $('.popup-marker').popover('hide'); }); 

如何在页面上的其他任何地方点击closurespopup窗口,但不能点击popup窗口本身?

假定在任何时候只有一个popup窗口是可见的,你可以使用一组标记来标记popup窗口是否可见,然后才能隐藏它们。

如果您在文档正文上设置了事件侦听器,那么当您单击标有“popup-marker”的元素时,它将触发。 所以你必须在事件对象上调用stopPropagation() 。 点击popup窗口本身时应用相同的技巧。

下面是一个正在运行的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个。 但是我认为这会让用户感到困惑,无论如何:-)

这更容易:

 $('html').click(function(e) { $('.popup-marker').popover('hide'); }); $('.popup-marker').popover({ html: true, trigger: 'manual' }).click(function(e) { $(this).popover('toggle'); e.stopPropagation(); }); 

我也有类似的需求,并且发现了Lee Carmichael推出的Twitter Bootstrap Popover的一个很好的扩展,名为BootstrapX – clickover 。 他在这里也有一些用法示例。 基本上,它会将popup窗口变成一个交互式的组件,当你点击页面上的其他地方,或者popup窗口中的closuresbutton时,它将closures。 这也将允许一次打开多个popup窗口和一堆其他不错的function。

插件可以在这里find 。

用法示例

 <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(); 

被接受的解决scheme给了我一些问题(点击打开的popover的“.popup-marker”元素,使得popovers不起作用)。 我想出了另一个完全适合我的解决scheme,它非常简单(我使用的是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!

阅读“closures点击”这里http://getbootstrap.com/javascript/#popovers

您可以使用焦点触发器来closures下一次点击的popup窗口,但是您必须使用<a>标记,而不是<button>标记,还必须包含tabindex属性…

例:

 <a href="#" tabindex="0" class="btn btn-lg btn-danger" data-toggle="popover" data-trigger="focus" title="Dismissible popover" data-content="And here's some amazing content. It's very engaging. Right?"> Dismissible popover </a> 

https://github.com/lecar-red/bootstrapx-clickover

它是twitter bootstrap popover的扩展,将会很简单地解决这个问题。

所有现有的答案相当薄弱,因为他们依靠捕获所有文档事件,然后find活动的popup窗口,或修改调用.popover()

更好的方法是听取文档主体上的show.bs.popover事件,然后做出相应的反应。 下面是代码,当文件被点击或esc被按下时会closurespopup窗口,当popup显示时绑定事件监听器:

 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); } 

出于某种原因,这里没有其他解决scheme为我工作。 但是,经过很多故障排除之后,我终于到达了这个完美工作的方法(至less对我来说)。

 $('html').click(function(e) { if( !$(e.target).parents().hasClass('popover') ) { $('#popover_parent').popover('destroy'); } }); 

在我的情况下,我添加了一个popover到一个表,绝对定位它上面/下面的点击td 。 表select是由jQuery-UIselect处理,所以我不知道这是干扰。 然而,每当我点击里面的popup我的点击处理程序的目标$('.popover')从来没有工作和事件处理总是委托给$(html)点击处理程序。 我相当新的JS,所以也许我只是失去了一些东西?

无论如何,我希望这可以帮助别人!

我给我所有的popovers锚点类activate_popover 。 我一下子激活它们

$('body').popover({selector: '.activate-popover', html : true, container: 'body'})

获取我使用的点击function(在咖啡脚本中):

 $(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') ) 

这与引导2.3.1完美无瑕

即使这里有很多解决scheme,我也想build议我的,我不知道是否有解决这个问题的一些解决scheme,但我尝试了3个,他们有问题,如点击在popup它自己使其隐藏,其他人,如果我有另一个popupbutton点击两个/多个popup仍然会出现(如在选定的解决scheme),如何永远, 这一个固定它

 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(); }); 

如果有帮助的话,下面是对我来说工作得很好的解决scheme:

 /** * 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; } }); }); 

这是我的解决scheme,它是值得的:

 // 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"); } }); }); 

我有一些问题让它在引导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 }); }); 

微调@David Wolever解决scheme:

 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); } 

这个问题也在这里被问到,我的答案不仅提供了一种理解jQuery DOM遍历方法的方法,而且还提供了两种通过单击外部来处理closurespopovers的选项。

一次打开多个popup窗口或一次打开一个popup窗口。

再加上这些小代码片段可以处理closures包含图标的button!

https://stackoverflow.com/a/14857326/1060487

这个作品像一个魅力,我使用它。

它会打开popup窗口,当你点击,如果你再次点击它将closures,如果你点击popup窗口外popup窗口将被closures。

这也适用于超过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(); }); 

我将焦点设置为新创build的popup窗口,并将其删除。 这样就不需要检查DOM的哪个元素被点击了,popup窗口可以被点击,也可以被选中:它不会失去焦点,也不会消失。

代码:

  $('.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'); }); 

我做如下

 $("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'); }); }); } }); 

希望这可以帮助!

如果你正在尝试使用pjax的twitter引导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); }); 

@RayOnAir,我有与以前的解决scheme相同的问题。 我也接近@RayOnAir解决scheme。 有一点改进是closures已经打开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; } }); 

我发现这是上面pbaron的build议的一个修改的解决scheme,因为他的解决scheme激活popup窗口('隐藏')的所有类与'popup标记'的元素。 然而,当你使用popover()来代替html内容而不是数据内容时,如下所示,那个htmlpopup窗口中的任何点击实际上都会激活popup窗口('hide'),这会立即closures窗口。 下面的方法遍历每个.popup-marker元素,并首先发现父级是否与被点击的.popup-marker的id相关,如果是,则不会隐藏它。 所有其他divs被隐藏…

  $(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(); }); }); 

我想出了这个:

我的情景在同一页面上包含了更多的popup窗口,隐藏它们只是使它们不可见,因此点击popover后面的项目是不可能的。 这个想法是把特定的popover-link标记为“active”,然后你可以简单地“切换”活动的popover。 这样做会完全closurespopover。

 $('.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" 

我试图为一个简单的问题做一个简单的解决scheme。 以上post很好,但对于一个简单的问题来说太复杂了。 所以我做了一件简单的事情。 刚刚添加了一个closuresbutton。 它对我来说是完美的。

  $(".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; } 

我喜欢这个,简单而有效

 var openPopup; $('[data-toggle="popover"]').on('click',function(){ if(openPopup){ $(openPopup).popover('hide'); } openPopup=this; }); 

btn-popover类添加到popupbutton/链接中,以打开popup窗口。 此代码将在点击外部时closurespopup窗口。

 $('body').on('click', function(event) { if (!$(event.target).closest('.btn-popover, .popover').length) { $('.popover').popover('hide'); } }); 

一个更简单的解决scheme,只是遍历所有的popup窗口,如果不是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'); } }); }); 

尝试data-trigger="focus"而不是"click"

这解决了我的问题。

 jQuery(':not(.popup-marker)').once().click(function(){ jQuery('.popup-marker').hide(); });