如何在页面上的任何位置(其他位置)单击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!
这个作品像一个魅力,我使用它。
它会打开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(); });