如何通过单击页面上的任何位置(其他)来关闭 Twitter Bootstrap 弹出窗口?

IT技术 javascript jquery twitter-bootstrap
2021-02-13 14:22:11

我目前正在使用带有 Twitter Bootstrap 的弹出框,如下所示:

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

如您所见,它们是手动触发的,单击 .popup-marker(带有背景图像的 div)会切换弹出框。这很好用,但我也希望能够通过点击页面上的其他任何地方(但不是在弹出框本身上!)来关闭弹出框。

我尝试了一些不同的事情,包括以下内容,但没有显示结果:

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

如何通过单击页面上的其他任何位置而不是单击弹出框本身来关闭弹出框?

6个回答

假设在任何时候只有一个弹出窗口可见,您可以使用一组标志来标记何时有一个弹出窗口可见,然后才隐藏它们。

如果你在文档正文上设置了事件监听器,它会在你点击标有'popup-marker'的元素时触发。所以你必须调用stopPropagation()事件对象。并在单击弹出窗口本身时应用相同的技巧。

下面是执行此操作的有效 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 个弹出窗口。但我认为这会让用户感到困惑,无论如何:-)

为什么不在 $(this).popover('show') 之前运行 $('.popup-marker').popover('hide') (将它们全部隐藏),这样就不需要任何 isVisible 和 clickedAway 变量?
2021-03-16 14:22:11
这个解决方案给了我一些问题(点击打开的弹出框的“.popup-marker”元素后弹出框不起作用)。我想出了另一个对我有用并且看起来更简单的解决方案(在下面发布)(我使用的是 Bootstrap 2.3.1)。
2021-03-18 14:22:11
@RaduCugut 这是一个很好的解决方案。但它有一个错误。单击 zzzzz 一次,弹出窗口就会出现。现在在白色背景上单击一次。弹出窗口消失。现在再次单击白色背景。现在再次单击zzzz,它不起作用。:-|
2021-03-25 14:22:11
@Kave你是对的,我已经修改了小提琴和纠正这个问题的答案。jsfiddle.net/AFffL/177
2021-04-04 14:22:11
单击该 jsfiddle 中的弹出框本身会导致弹出框隐藏 - 不是 tnorthcutt 所要求的。
2021-04-07 14:22:11

这更容易:

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

$('.popup-marker').popover({
    html: true,
    trigger: 'manual'
}).click(function(e) {
    $(this).popover('toggle');
    e.stopPropagation();
});
这是 IMO 的最佳答案。
2021-03-20 14:22:11
这样做的一个问题是弹出窗口仍然存在,只是隐藏了。因此,例如,如果您在弹出窗口中有链接,您可以将光标悬停在它以前所在的位置,并且仍然让光标在这些链接上发生变化。
2021-03-23 14:22:11
@pbaron 和 @Cornelis 答案的汇编效果最好。我添加的是第二个“单击”函数中的 Cornelis 代码(就在$(this).popover('toggle');部分之前。然后,如果您有多个“弹出标记”对象,单击每个对象将关闭其他对象。
2021-03-24 14:22:11
希望使用它,但由于某种原因没有成功。点击事件从未达到,html因为e.stopPropagation();相反,我使用了类似的东西$('.popup-marker').on('show', function(event) { $('.popup-marker').filter(function(index, element) { return element != event.target; }).popover('hide'); });,它也做得很好(虽然不知道是否存在性能差异)
2021-03-26 14:22:11
同意。至少对我来说,这是正确的做法。第一个选项似乎是“快速修复”。
2021-03-31 14:22:11

我有类似的需求,并发现了 Lee Carmichael 的 Twitter Bootstrap Popover 的这个很棒的小扩展,称为 BootstrapX - clickover在这里也有一些使用示例基本上它会将弹出窗口更改为一个交互式组件,当您单击页面上的其他地方或弹出窗口中的关闭按钮时,该组件将关闭。这也将允许同时打开多个弹出窗口和一堆其他不错的功能。

插件可以在这里找到

使用示例

<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();
刚刚试了一下,效果很好。就像将现有 popover 的 rel 从“popover”更改为“clickover”一样简单。
2021-03-19 14:22:11
优秀的插件!谢谢你的链接。
2021-03-23 14:22:11
在 Bootstrap v2.3.1 上运行,没有问题。
2021-03-23 14:22:11
这真的很棒。超级容易。
2021-04-04 14:22:11

接受的解决方案给了我一些问题(单击打开的弹出框的“.popup-marker”元素使弹出框之后无法工作)。我想出了另一个非常适合我的解决方案,它非常简单(我使用的是 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!

这是一个很好的解决方案。谢谢你。
2021-03-21 14:22:11
或更好 if (!$(e.target).is('.popup-marker') && $(e.target).closest('.popover').length === 0)
2021-04-01 14:22:11
很好的解决方案。你为什么不使用 if (!$(e.target).is('.popup-marker') && !$(e.target).parents('.popover').length > 0)这种方式,即使它有 html 内容,弹出窗口也不会关闭
2021-04-04 14:22:11

http://getbootstrap.com/javascript/#popovers阅读“在下次点击时关闭”

您可以使用焦点触发器在下次单击时关闭弹出窗口,但您必须使用<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>
该问题表示,如果点击是在弹出窗口上,他不希望它被关闭。这在任何地方的任何点击都会关闭它。
2021-04-02 14:22:11
添加 data-trigger="focus" 阻止了我的弹出窗口启动,直到我阅读了这篇文章并添加了 tabindex 属性。现在它起作用了!
2021-04-04 14:22:11
有关信息,这也适用于tooltip,即使实际文档中没有明确提及。
2021-04-05 14:22:11