Twitter bootstrap 如何通过点击外部关闭Twitter引导弹出窗口?

Twitter bootstrap 如何通过点击外部关闭Twitter引导弹出窗口?,twitter-bootstrap,popover,Twitter Bootstrap,Popover,我们能不能让弹出框和情态动词一样可以关闭,也就是说,当用户点击弹出框之外的某个地方时关闭弹出框 不幸的是,我不能用实模态代替popover,因为模态意味着位置:固定,那就不再是popover了(我制作了一个jsfiddle来向您展示如何做: 其思想是在单击按钮时显示弹出框,在单击按钮外部时隐藏弹出框 HTML 这基本上不是很复杂,但需要进行一些检查以避免出现故障 var$poped=$('someselector'); //爆米花的扳机 $poped.each(函数(){ var$this=

我们能不能让弹出框和情态动词一样可以关闭,也就是说,当用户点击弹出框之外的某个地方时关闭弹出框


不幸的是,我不能用实模态代替popover,因为模态意味着位置:固定,那就不再是popover了(

我制作了一个jsfiddle来向您展示如何做:

其思想是在单击按钮时显示弹出框,在单击按钮外部时隐藏弹出框

HTML
这基本上不是很复杂,但需要进行一些检查以避免出现故障

var$poped=$('someselector');
//爆米花的扳机
$poped.each(函数(){
var$this=$(this);
$this.on('hover',function(){
var popover=$this.data('popover');
显示的var=popover&&popover.tip().is(“:可见”);
如果(显示)返回;//避免闪烁
$this.popover('show');
});
});
//隐藏的触发器
$('html')。on('click.popover.dataapi',function()){
$poped.popover('hide');
});

以前有人问过这个问题。我当时给出的答案仍然适用:


我也有类似的需求,并发现了这一点。他还提供了一些使用示例。基本上,它会将popover更改为一个交互式组件,当您单击页面上的其他位置或popover中的“关闭”按钮时,该组件将关闭。这也将允许同时打开多个popover和一系列其他优秀功能。

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

jQuery("#menu").click(function(){ return false; });
jQuery(document).one("click", function() { jQuery("#menu").fadeOut(); });
$('body').on('click touchstart', '.popover-close', function(e) {
  return $(this).parents('.popover').remove();
});

在html中,将.popover close类添加到popover中应关闭popover的内容中。

更新:一个更健壮的解决方案:

对于仅包含文本的按钮:

$('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中有一个bug,请参阅下面回答中的修复)

对于JS生成的弹出窗口使用
'[data original title]'
代替
'[data toggle=“popover”]'

警告:上述解决方案允许同时打开多个弹出窗口

请一次一个爆米花:

更新:Bootstrap 3.0.x,请参阅代码或小提琴

这将处理关闭已打开但未单击或其链接未单击的弹出窗口


更新:引导程序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");
            }
        }
    });
});
演示:

}

这是我的解决方案

$('html').on('mouseup', function(e) {
    if(!$(e.target).closest('.popover').length) {
        $('.popover').each(function(){
            $(this.previousSibling).popover('hide');
        });
    }
});
如果单击除popover外的任何位置,则会关闭所有popover

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

此方法确保您可以通过单击页面上的任意位置来关闭一个弹出窗口。如果您单击另一个可单击的实体,它将隐藏所有其他弹出窗口。动画:false是必需的,否则您将获得jquery。请删除控制台中的错误

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

这项功能在最新的引导程序中是否真正起到了开箱即用的作用似乎还不太清楚(如果你愿意在用户可以点击的地方妥协的话)。我不确定你是否必须把“点击悬停”本身放在iPad上,但在iPad上,点击可以作为一种切换

最终的结果是,在桌面上,您可以悬停或单击(大多数用户都会悬停)。在触摸设备上,触摸元素会将其打开,再次触摸元素会将其关闭。当然,这与您最初的要求略有不同,但至少您的代码现在更干净了:)

$(“.my popover”).popover({ 触发器:“单击悬停” }))


使用bootstrap 2.3.2,您可以将触发器设置为“焦点”,并且它可以正常工作:

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

派对已经晚了…但我想我会和大家分享的。 我喜欢popover,但它的内置功能太少了。我编写了一个引导扩展。bubble(),这就是我希望popover成为的一切。有四种方法可以消除。单击外部,切换链接,单击X,然后单击escape

它会自动定位,因此不会离开页面


这不是一个无缘无故的自我推销……我一生中多次抓住别人的代码,我想贡献自己的力量。试试看它是否适合你。

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

演示:

演示2:在popover内容中单击时不放弃

演示3:多个弹出窗口:


只需拨打这一行,就会关闭所有弹出窗口:

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

使用此代码单击外部时,关闭所有弹出窗口:

$('html').on('click', function(e) {
  if (typeof $(e.target).data('original-title') == 'undefined') {
    $('[data-original-title]').popover('hide');
  }
});
上面的代码段在主体上附加了一个单击事件。 当用户单击popover时,它的行为将正常。 当用户单击不是popover的内容时,它将关闭所有popover

$('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
            }
        }
    });
});
它还可以用于使用Javascript启动的弹出窗口,而不是其他一些不起作用的示例(参见演示)

如果您不想在popover内容内单击时退出,请使用以下代码(请参阅第二个演示的链接):

我想到了这个: 我的场景包括在同一页上有更多的弹出框,隐藏它们只会使它们不可见,因此,单击弹出框后面的项目是不可能的。 其想法是将特定的popover链接标记为“活动”,然后您可以简单地“切换”活动popover。这样做将完全关闭popover $('.popover link').popover({html:true,容器:'body'})


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


以Matt Lockyer的代码为例,我做了一个简单的重置,这样dom就不会被el覆盖
$('.clickable').popover({
 trigger: 'manual',
 animation: false
 }).click (evt) ->
  $('.clickable').popover('hide')
  evt.stopPropagation()
  $(this).popover('show')

$('html').on 'click', (evt) ->
  $('.clickable').popover('hide')
$('#el').popover({trigger:'focus'});
$('[data-original-title]').popover('hide');
$('html').on('click', function(e) {
  if (typeof $(e.target).data('original-title') == 'undefined') {
    $('[data-original-title]').popover('hide');
  }
});
$('html').on('click', function(e) {
  if (typeof $(e.target).data('original-title') == 'undefined' && !$(e.target).parents().is('.popover.in')) {
    $('[data-original-title]').popover('hide');
  }
});
$('.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"
$(".my-popover").popover();

$(".my-popover").on('show.bs.popover',function () {
    $('.popover.in').remove();
});              
    $('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');
    }
    });
});
<button type="button" class="popover-dismiss" data-toggle="popover" title="Dismissible popover" data-content="Popover Content">Dismissible popover</button>
$('.popover-dismiss').popover({
    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');
        }
    });
});
$(document.body').popover({selector: '[data-toggle=popover]'});
$(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();
        }
    });
});
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');
        }
}
$(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');
        }
    });
})
$('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
            }
        }
    });
});
        $('[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');
                }
            });
        });
$('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"
data-trigger="focus"
<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>
$("body")   .on('click'     ,'[data-toggle="popover"]', function(e) { 
    e.stopPropagation();
});

$("body")   .on('click'     ,'.popover' , function(e) { 
     e.stopPropagation();
});

$("body")   .on('click'  , function(e) {
        $('[data-toggle="popover"]').popover('hide');
});