如何通过点击外部解雇Twitter Bootstrappopup窗口?

我们能不能像模式一样使pop-up成为可以忽略的。 当用户点击他们之外的地方时,让他们closures?

不幸的是,我不能仅仅使用真正的模态而不是popup式,因为模式意味着位置:固定的,那将不再是popup式的。 🙁

更新:一个更健壮的解决scheme: http : //jsfiddle.net/mattdlockyer/C5GBU/72/

对于仅包含文本的button:

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

对于包含图标的button使用(此代码在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"]'

警告:上面的解决scheme允许多个popup一次打开。

一次一个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'); } }); }); 

这处理closures已经打开并没有点击的链接,或者链接没有被点击。


更新: Bootstrap 3.3.6, 看小提琴

修复了closures后的问题,需要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 } }); }); 
 $('html').on('mouseup', function(e) { if(!$(e.target).closest('.popover').length) { $('.popover').each(function(){ $(this.previousSibling).popover('hide'); }); } }); 

如果您点击popup窗口以外的任何位置,则会closures所有popup窗口

最简单,最安全的版本 ,适用于任何引导版本。

演示: http : //jsfiddle.net/guya/24mmM/

演示2:在点击popup窗口内容时不放弃http://jsfiddle.net/guya/fjZja/

演示3:多个popovers: http : //jsfiddle.net/guya/6YCjW/


只需调用这一行就可以忽略所有的stream行:

 $('[data-original-title]').popover('hide'); 

使用此代码在外部点​​击时closures所有popup窗口:

 $('html').on('click', function(e) { if (typeof $(e.target).data('original-title') == 'undefined') { $('[data-original-title]').popover('hide'); } }); 

上面的代码片段在主体上附加了一个点击事件。 当用户点击一个popover时,它将像正常一样运行。 当用户点击某个不是popup窗口的东西时,它将closures所有popup窗口。

它也将使用Javascript启动的popovers,而不是其他一些不起作用的例子。 (看演示)

如果您不想在点击popup窗口内容时解雇,请使用此代码(请参阅第二个演示的链接):

 $('html').on('click', function(e) { if (typeof $(e.target).data('original-title') == 'undefined' && !$(e.target).parents().is('.popover.in')) { $('[data-original-title]').popover('hide'); } }); 

这基本上不是很复杂,但有一些检查,以避免小故障。

演示(jsfiddle)

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

使用bootstrap 2.3.2,你可以设置触发器为“焦点”,它只是工作:

 $('#el').popover({trigger:'focus'}); 

没有人认为我的答案是正确的。 当打开和closures(通过点击其他元素)第一次popup时,每个导致一个错误,它不会再次打开,直到你在触发链接而不是一个点击。

所以我修改了一下:

 $(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,告诉你如何做到这一点:

http://jsfiddle.net/3yHTH/

这个想法是当你点击button时显示popup窗口,当你点击button外时隐藏popup窗口。

HTML

 <a id="button" href="#" class="btn btn-danger">Click for popover</a> 

JS

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

这已经在这里被问过。 我给出的同样的答案仍然适用:

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

这是晚了…但我想我会分享它。 我喜欢popover,但内置的function很less。 我写了一个bootstrap扩展.bubble(),这就是我想popover的一切。 四种解雇方式。 点击外面的链接,点击X,然后点击转义。

它自动定位,所以它永远不会离开页面。

https://github.com/Itumac/bootstrap-bubble

这不是一个无偿的自我推销…我一辈子都抓了别人的代码,我想提供自己的努力。 给它一个旋转,看看它是否适合你。

 jQuery("#menu").click(function(){ return false; }); jQuery(document).one("click", function() { jQuery("#menu").fadeOut(); }); 

您还可以使用事件冒泡从DOM中删除popup窗口。 这有点脏,但工作正常。

 $('body').on('click touchstart', '.popover-close', function(e) { return $(this).parents('.popover').remove(); }); 

在你的html中,将.popover-close类添加到应该closurespopup窗口的popup窗口中。

根据http://getbootstrap.com/javascript/#popovers

 <button type="button" class="popover-dismiss" data-toggle="popover" title="Dismissible popover" data-content="Popover Content">Dismissible popover</button> 

使用焦点触发器closures用户下一次点击的popup。

 $('.popover-dismiss').popover({ trigger: 'focus' }) 

看起来'隐藏'方法不起作用,如果你使用select器委托创buildpopover,而不是'destroy'必须被使用。

我做了这样的工作:

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

JSfiddle在这里

我们发现我们的解决scheme来自@mattdlockyer(感谢解决scheme!)。 当使用popup式构造函数的select器属性像这样…

 $(document.body').popover({selector: '[data-toggle=popover]'}); 

…为BS3提出的解决scheme将无法正常工作。 相反,它会在$(this)创build第二个popover实例。 这是我们的解决scheme,以防止:

 $(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'); 将由于委派的监听器而创build第二个实例。 提供的解决scheme只隐藏已经实例化的popovers。

我希望我能救一些时间。

修改后接受的解决 我所经历的是,在隐藏了一些popup之后,必须再次点击两次以再次出现。 这是我做了什么来确保popover('hide')没有在已经隐藏的popovers上被调用。

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

Bootstrap 本地支持 :

JS斌演示

特定标记需要解雇的下一次点击

对于正确的跨浏览器和跨平台行为,您必须使用<a>标记, 而不是 <button>标记,还必须包含role="button"tabindex属性。

这个解决scheme在第二次显示popover时摆脱了讨厌的第二次点击

使用Bootstrap v3.3.7进行testing

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

只需将该属性添加到该元素即可

 data-trigger="focus" 

显示新的popup窗口之前,我只删除其他活动的弹窗(引导程序3):

 $(".my-popover").popover(); $(".my-popover").on('show.bs.popover',function () { $('.popover.in').remove(); }); 

演示: 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; }); 

}

这是我的解决scheme。

这种方法确保您可以通过单击页面上的任何位置来closurespopup窗口。 如果你点击另一个可点击的实体,它隐藏所有其他的popup。 animation:假是必须的,否则你会在你的控制台中得到一个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') 

好吧,这是我第一次尝试在stackoverflow上实际回答的东西,所以这里什么也不做:P

看起来,这个function实际上在最新的引导程序中是可以实现的(不过,如果你愿意在用户可以点击的地方妥协的话,这个function并不是很清楚),我不确定你是否必须把点击hover“,但在iPad上,单击工具作为切换。

最终的结果是,在桌面上,你可以hover或点击(大多数用户将hover)。 在触摸设备上,触摸该元件将会提起,然后再次触摸它会将其取下。 当然,这是从你原来的要求轻微的妥协,但至less你的代码现在是干净的:)

$(“。my-popover”)。popover({trigger:'click hover'});

我想出了这个:我的场景在同一页面上包含了更多的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" 

以Matt Lockyer的代码,我做了一个简单的重置,所以dom没有被隐藏的元素覆盖。

马特的代码: 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的解决scheme的问题,因为我使用这样的代码dynamic地设置popup链接:

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

请记住,摧毁摆脱元素,所以select器部分是非常重要的初始化popup。

@guya的答案是有效的,除非你在popover中有一个类似于datepicker或timepicker的东西。 为了解决这个问题,这就是我所做的。

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

这是我最好的性能解决scheme。 干杯。

答案很好,只要添加一个angular度指令,以防你使用像我这样的angular度:

 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:

popup如何触发 – 单击| hover| 重点| 手册。 你可能传递多个触发器; 用空格分开。 手动不能与任何其他触发器组合。

但是,一起使用点击和聚焦不适用于我不知道的原因,而不得不手动切换。

用3.3.6进行testing,第二次点击就OK了

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