如何在Bootstrap的弹出框中插入关闭按钮

79

JS:

$(function(){
  $("#example").popover({
    placement: 'bottom',
    html: 'true',
    title : '<span class="text-info"><strong>title</strong></span> <button type="button" id="close" class="close">&times;</button>',
    content : 'test'
  })
  $('html').click(function() {
    $('#close').popover('hide');
  });
});

HTML:

<button type="button" id="example" class="btn btn-primary" ></button>

我编写的代码没有显示弹出窗口。

有人遇到过这个问题吗?

28个回答

92
你需要确保标记正确。
<button type="button" id="example" class="btn btn-primary">example</button>

然后,一种方法是将关闭处理程序附加在元素内部,以下内容有效:

$(document).ready(function() {
    $("#example").popover({
        placement: 'bottom',
        html: 'true',
        title : '<span class="text-info"><strong>title</strong></span>'+
                '<button type="button" id="close" class="close" onclick="$(&quot;#example&quot;).popover(&quot;hide&quot;);">&times;</button>',
        content : 'test'
    });
});  

11
onclick 替换为 data-dismiss="popover" 无效。这是一个被广泛记录的问题。 - Hengjie
1
在弹出框标题中使用内联HTML和JavaScript事件是一种非常糟糕的做法。它可能起作用,但以后会给你带来麻烦。 - Mario Fink
1
@Mario Fink(和Robert Kotcher)- 当然完全同意。但这就是您可以在Twitter Bootstrap 2.x中实现所需功能的方式,现在预期的方式失败了。我只是回答问题。 - davidkonrad
1
我刚刚注意到,执行 $(elm).popover('hide') 有时(我不确定是否总是如此)会让弹出窗口保持在原位,并添加一个 .fade 类,使其透明度为0。这会导致用户无法选择文本等问题。更好的解决方法是使用 $(elm).popover('toggle') - Swashata Ghosh
2
对我来说,上面的例子只有将双引号(")替换为单引号(')才能正常工作。 - Ruut
显示剩余10条评论

33

我需要找到适用于多个弹出框且适用于Bootstrap 3的解决方案。

这是我所做的:

我有多个元素需要使用弹出框,所以我不想使用ID。

标记可以如下:

<button class="btn btn-link foo" type="button">Show Popover 1</button>
<button class="btn btn-link foo" type="button">Show Popover 2</button>
<button class="btn btn-link foo" type="button">Show Popover 3</button>

弹出框中保存和关闭按钮的内容:

var contentHtml = [
    '<div>',
        '<button class="btn btn-link cancel">Cancel</button>',
        '<button class="btn btn-primary save">Save</button>',
    '</div>'].join('\n');

和所有3个按钮的javascript代码:

当容器为默认值且未附加到body时,此方法可行。

$('.foo').popover({
    title: 'Bar',
    html: true,
    content: contentHtml,
    trigger: 'manual'
}).on('shown.bs.popover', function () {
    var $popup = $(this);
    $(this).next('.popover').find('button.cancel').click(function (e) {
        $popup.popover('hide');
    });
    $(this).next('.popover').find('button.save').click(function (e) {
        $popup.popover('hide');
    });
});

当容器附加到 'body' 时

然后,使用 aria-describedby 查找弹出窗口并隐藏它。

$('.foo').popover({
    title: 'Bar',
    html: true,
    content: contentHtml,
    container: 'body',
    trigger: 'manual'
}).on('shown.bs.popover', function (eventShown) {
    var $popup = $('#' + $(eventShown.target).attr('aria-describedby'));
    $popup.find('button.cancel').click(function (e) {
        $popup.popover('hide');
    });
    $popup.find('button.save').click(function (e) {
        $popup.popover('hide');
    });
});

小改进:popup.find('button.cancel').on('click',function(e) {...} - bart
7
当我点击取消链接时,它会关闭弹出窗口。但是当我第一次点击弹出窗口触发链接时,弹出窗口不会打开,我必须再点击一次。 - Nizam Kazi
有一个预定义的类.close,带有悬停效果,因此将关闭按钮插入标题或内容就像这样简单:<span class=close>&times;</span> - lubosdz
@NizamKazi 使用我下面的解决方案来解决问题:https://dev59.com/r2Yr5IYBdhLWcg3wxM0k#58923567 - TetraDev

29

我发现其他答案要么不够通用,要么太复杂。这里有一个简单的解决方法,应该始终有效(适用于bootstrap 3):

$('[data-toggle="popover"]').each(function () {
    var button = $(this);
    button.popover().on('shown.bs.popover', function() {
        button.data('bs.popover').tip().find('[data-dismiss="popover"]').on('click', function () {
            button.popover('toggle');
        });
    });
});

只需在关闭按钮中添加属性data-dismiss="popover"。同时,请确保不要在代码的其他位置使用popover('hide'),因为它会隐藏弹出窗口,但不会正确设置其在Bootstrap代码中的内部状态,这将导致下次使用popover('toggle')时出现问题。


2
由于某些原因,使用Bootstrap 3时,.popover('toggle');对我来说从未起作用,而.popover('hide');确实有效。除此之外,这个解决方案是我最喜欢的。谢谢! - hvaughan3
这样做会不会在每个弹出显示事件上绑定点击事件,导致多次绑定? - pdu
@pduersteler 这是旧代码,但它在生产中使用,所以我很确定它能正常工作。我猜bootstrap每次单击按钮时都会创建一个新的弹出窗口,因此也会创建一个新的关闭按钮。如果关闭按钮上有多个事件,它将多次切换,我应该会注意到这个错误(希望如此)。如果您能确认问题,请告诉我。想了想,也许这就是我遇到popover('hide')无法销毁弹出窗口而只是隐藏它的原因? - youen
1
在现代的Bootstrap(>= 4?)中,这应该是$(button.data('bs.popover').tip).find('[data-dismiss="popover"]') - Mike Campbell

20

之前的示例有两个主要缺点:

  1. “关闭”按钮需要以某种方式知道所引用元素的ID。
  2. 需要在“shown.bs.popover”事件上添加一个“click”监听器来关闭弹出框,这也不是一个好的解决方案,因为每次显示“popover”时都会添加此侦听器。

下面是一种没有这些缺点的解决方案。

默认情况下,“popover”元素立即插入到DOM中的所引用元素之后(因此请注意所引用元素和popover是立即兄弟元素)。因此,当单击“关闭”按钮时,您可以简单地查找其最近的“div.popover”父项,然后查找其父项的直接前一个同胞元素。

只需将以下代码添加到“关闭”按钮的“onclick”处理程序中即可:

$(this).closest('div.popover').popover('hide');

例子:

var genericCloseBtnHtml = '<button onclick="$(this).closest(\'div.popover\').popover(\'hide\');" type="button" class="close" aria-hidden="true">&times;</button>';

$loginForm.popover({
    placement: 'auto left',
    trigger: 'manual',
    html: true,
    title: 'Alert' + genericCloseBtnHtml,
    content: 'invalid email and/or password'
});

2
哇,好棒又简单的解决方案。对我很有效。 - Adrian Enriquez
8
在 Bootstrap 4.3 中,我需要在弹出框选项中添加 sanitize: false - Richard

15

进入图像描述

以下是我刚在我的项目中使用的内容。希望它能帮到你。

<a id="manualinputlabel" href="#" data-toggle="popover" title="weclome to use the sql quer" data-html=true  data-original-title="weclome to use the sql query" data-content="content">example</a>


$('#manualinputlabel').click(function(e) {
              $('.popover-title').append('<button id="popovercloseid" type="button" class="close">&times;</button>');
              $(this).popover();

          });

      $(document).click(function(e) {
         if(e.target.id=="popovercloseid" )
         {
              $('#manualinputlabel').popover('hide');                
         }

      });

嘿,谢谢你的回答!你知道如何在 h3.popover-title 对象中垂直居中 &times; 符号吗? - Renato Gama
工作得很好,但我在垂直对齐方面遇到了同样的问题。我为关闭按钮添加了自己的类,并使用 line-height: 0.7 !important;,看起来不错。 - dading84
当我点击取消链接时,它会关闭弹出窗口。但是,当我第一次单击弹出窗口触发器链接时,它不会打开弹出窗口,我必须再次单击。 - Shurvir Mori

10

我已经检查了许多提到的代码示例,对我而言,Chris的方法完美地运行。我在此添加了我的代码,以便有一个工作演示。

我已经使用Bootstrap 3.3.1进行了测试,但我没有测试过旧版本。但它肯定不适用于2.x,因为shown.bs.popover事件是在3.x中引入的。

$(function() {
  
  var createPopover = function (item, title) {
                       
        var $pop = $(item);
        
        $pop.popover({
            placement: 'right',
            title: ( title || '&nbsp;' ) + ' <a class="close" href="#">&times;</a>',
            trigger: 'click',
            html: true,
            content: function () {
                return $('#popup-content').html();
            }
        }).on('shown.bs.popover', function(e) {
            //console.log('shown triggered');
            // 'aria-describedby' is the id of the current popover
            var current_popover = '#' + $(e.target).attr('aria-describedby');
            var $cur_pop = $(current_popover);
          
            $cur_pop.find('.close').click(function(){
                //console.log('close triggered');
                $pop.popover('hide');
            });
          
            $cur_pop.find('.OK').click(function(){
                //console.log('OK triggered');
                $pop.popover('hide');
            });
        });

        return $pop;
    };

  // create popover
  createPopover('#showPopover', 'Demo popover!');

  
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" rel="stylesheet"/>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/js/bootstrap.min.js"></script>

<button class="btn btn-primary edit" data-html="true" data-toggle="popover" id="showPopover">Show</button>

<div id="popup-content" class="hide">
    <p>Simple popover with a close button.</p>
    <button class="btn btn-primary OK">OK</button>
</div>


1
我猜应该是 $cur_pop.popover('hide'); - Bernhard Döbler

5
诀窍是使用.data('bs.popover').tip()获取当前的弹出框:
$('#my_trigger').popover().on('shown.bs.popover', function() {
    // Define elements
    var current_trigger=$(this);
    var current_popover=current_trigger.data('bs.popover').tip();

    // Activate close button
    current_popover.find('button.close').click(function() {
        current_trigger.popover('hide');
    });
});

4
这适用于多个弹出窗口,我还添加了一些额外的JS来处理重叠弹出窗口时发生的z-index问题: http://jsfiddle.net/erik1337/fvE22/ JavaScript:
var $elements = $('.my-popover');
$elements.each(function () {
    var $element = $(this);

    $element.popover({
        html: true,
        placement: 'top',
        container: $('body'), // This is just so the btn-group doesn't get messed up... also makes sorting the z-index issue easier
        content: $('#content').html()
    });

    $element.on('shown.bs.popover', function (e) {
        var popover = $element.data('bs.popover');
        if (typeof popover !== "undefined") {
            var $tip = popover.tip();
            zindex = $tip.css('z-index');

            $tip.find('.close').bind('click', function () {
                popover.hide();
            });

            $tip.mouseover(function (e) {
                $tip.css('z-index', function () {
                    return zindex + 1;
                });
            })
                .mouseout(function () {
                $tip.css('z-index', function () {
                    return zindex;
                });
            });
        }
    });
});

HTML:

<div class="container-fluid">
    <div class="well popover-demo col-md-12">
        <div class="page-header">
             <h3 class="page-title">Bootstrap 3.1.1 Popovers with a close button</h3>

        </div>
        <div class="btn-group">
            <button type="button" data-title="Popover One" class="btn btn-primary my-popover">Click me!</button>
            <button type="button" data-title="Popover Two" class="btn btn-primary my-popover">Click me!</button>
            <button type="button" data-title="Popover Three (and the last one gets a really long title!)" class="btn btn-primary my-popover">Click me!</button>
        </div>
    </div>
</div>
<div id="content" class="hidden">
    <button type="button" class="close">&times;</button>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
</div>

CSS(层叠样式表):
/* Make the well behave for the demo */
 .popover-demo {
    margin-top: 5em
}
/* Popover styles */
 .popover .close {
    position:absolute;
    top: 8px;
    right: 10px;
}
.popover-title {
    padding-right: 30px;
}

4
只是想更新答案。根据Swashata Ghosh的说法,以下是一个更简单的方法,适用于moi:
HTML:
<button type="button" class="btn btn-primary example">Example</button>

JS:

$('.example').popover({
   title: function() {
      return 'Popup title' +
             '<button class="close">&times</button>';
   },
   content: 'Popup content',
   trigger: 'hover',
   html: true
});

$('.popover button.close').click(function() {
   $(this).popover('toggle');
});

4

我曾经也遇到过这个问题,以下是最简单的解决方法,只需要三行js代码:

  1. 在popover标题中添加一个叉号
  2. 使用js片段显示popover并通过点击标题关闭它
  3. 使用一些css样式使它更美观

enter image description here

$(document).ready(function() {
  // This is to overwrite the boostrap default and show it allways
  $('#myPopUp').popover('show');
  // This is to destroy the popover when you click the title
  $('.popover-title').click(function(){
    $('#myPopUp').popover('destroy');
  });
});
@import "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css";

/* Just to align my example */
.btn {
  margin: 90px auto;
  margin-left: 90px;
}

/* Styles for header */
.popover-title {
  border: 0;
  background: transparent;
  cursor: pointer;
  display: inline-block;
  float: right;
  text-align: right; 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
    
<button id="myPopUp" class="btn btn-success" data-toggle="popover" data-placement="top" data-title="×" data-content="lorem ipsum content">My div or button or something with popover</button>  
 


为什么交叉按钮不能通过Tab键导航? - Chandresh Mishra

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接