如何通过页面上的任何其他位置点击关闭Twitter Bootstrap弹出框?

156

我目前正在使用 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');
});

如何使弹出框在页面的任意其他位置单击时关闭,但不是在弹出框本身上单击?


嗯,我认为那应该可以运行...你有可能有在线链接吗? - thatryan
31个回答

2

我会把所有的弹出框锚点都赋予“activate_popover”这个类。在页面加载完毕时,我会一次性地激活它们。

$('body').popover({selector: '.activate-popover', html : true, container: 'body'})

为了让点击其他地方关闭弹出框的功能正常工作,我使用以下代码(使用coffee script):

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

这在使用Bootstrap 2.3.1时完全正常工作。


这对我有用,除了我必须在第一个if子句中摆脱.prev()。 我正在使用Bootstrap 3.2.0.2,也许有所不同? 此外,如果您希望能够同时打开多个弹出窗口,则可以完全省略第二个if子句。 只需单击任何不是弹出窗口激活元素(例如此示例中的类“activate-popover”)的位置即可关闭所有打开的弹出窗口。 运作良好! - Andrew Swihart

1

这是对我非常有效的解决方案,如果可以帮助到您:

/**
* 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;
        }        
    });
});

1
这个问题在这里也被问到了,我的答案不仅提供了理解jQuery DOM遍历方法的方式,还提供了两个选项来处理通过点击外部关闭弹出框的方式。
同时打开多个弹出框或一次只打开一个弹出框。
此外,这些小代码片段还可以处理包含图标的按钮的关闭!

https://dev59.com/KGgt5IYBdhLWcg3w8h01#14857326


1
稍微调整了 @David Wolever 的解决方案:
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);
}

1

另一个解决方案,它解决了我在单击弹出框后代元素时遇到的问题:

$(document).mouseup(function (e) {
    // The target is not popover or popover descendants
    if (!$(".popover").is(e.target) && 0 === $(".popover").has(e.target).length) {
        $("[data-toggle=popover]").popover('hide');
    }
});

1
这是我的解决方案,供参考:

Here's my solution, for what it's worth:

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

  });
});

1
这个非常好用,我在使用它。
当你点击时,它会打开弹出窗口,再次点击会关闭,如果你点击弹出窗口外部,弹出窗口也会关闭。
这也适用于多个弹出窗口。
    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();
});

这是唯一对我起作用的版本。Bootstrap 3.20。谢谢。 - Telegard

1

我在使用Bootstrap 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
    });
});

0

我喜欢这个,简单而有效。

var openPopup;

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

    }
    openPopup=this;
});

0

我试图为一个简单的问题找到一个简单的解决方案。上面的帖子都很好,但对于一个简单的问题来说太复杂了。所以我做了一件简单的事情。只是添加了一个关闭按钮。这对我来说非常完美。

            $(".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;
    }

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