Como posso fechar um popover do Twitter Bootstrap com um clique de qualquer outro lugar da página?

155

Atualmente, estou usando popovers com o Twitter Bootstrap, iniciado assim:

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

Como você pode ver, eles são acionados manualmente e clicar em .popup-marker (que é uma div com uma imagem de fundo) alterna uma janela popover. Isso funciona muito bem, mas eu também gostaria de fechar o popover com um clique em qualquer outro lugar da página (mas não no popover em si!).

Eu tentei algumas coisas diferentes, incluindo as seguintes, mas sem resultados para mostrar:

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

Como posso fechar o popover com um clique em qualquer outro lugar da página, mas não com um clique no popover em si?

Travis Northcutt
fonte
Hum, eu acho que isso funcionaria ... você tem um link para isso online por acaso?
thatryan

Respostas:

102

Supondo que apenas um popover possa estar visível a qualquer momento, você pode usar um conjunto de sinalizadores para marcar quando há um popover visível e só depois ocultá-los.

Se você definir o ouvinte de evento no corpo do documento, ele será acionado quando você clicar no elemento marcado com 'pop-up-marker'. Então você terá que chamar stopPropagation()o objeto de evento. E aplique o mesmo truque ao clicar no popover em si.

Abaixo está um código JavaScript funcional que faz isso. Ele usa 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/

A única ressalva é que você não poderá abrir dois popovers ao mesmo tempo. Mas acho que seria confuso para o usuário :-)

Radu Cugut
fonte
1
Clicar no popover em si nesse jsfiddle faz com que o popover oculte - não exatamente o que tnorthcutt pediu.
quer
1
@RaduCugut, é uma ótima solução. Mas tem um bug. Clique uma vez no zzzzz e o popover aparece. Agora clique uma vez no fundo branco. O pop-up desaparece. Agora clique novamente no fundo branco. E agora clique novamente no zzzz e ele não funciona. : - |
Houman 8/09/12
1
@ Você tem razão, eu modifiquei o violino e a resposta para corrigir isso. jsfiddle.net/AFffL/177
Radu Cugut
3
Por que não executar apenas $ ('. Popup-marker'). Popover ('hide') (para ocultar todos eles) antes de $ (this) .popover ('show'), o que elimina a necessidade de quaisquer variáveis ​​isVisible e clickedAway?
Nathan Hangen
1
Essa solução me deu alguns problemas (clicar no elemento '.popup-marker' do popover aberto fazia com que os popovers não funcionassem mais tarde). Eu vim com mais uma solução (postada abaixo) que funcionou para mim e parece mais simples (estou usando o Bootstrap 2.3.1).
RayOnAir
76

Isso é ainda mais fácil:

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

$('.popup-marker').popover({
    html: true,
    trigger: 'manual'
}).click(function(e) {
    $(this).popover('toggle');
    e.stopPropagation();
});
prbaron
fonte
Acordado. E pelo menos para mim, essa é a maneira certa de fazer isso. A primeira opção parece ser uma "solução rápida".
Denis Lins
4
Queria usar isso, mas por algum motivo não deu certo. Os eventos de clique nunca chegou htmlpor causa e.stopPropagation();Em vez disso eu usei algo como $('.popup-marker').on('show', function(event) { $('.popup-marker').filter(function(index, element) { return element != event.target; }).popover('hide'); });o que fez o trabalho muito bem também (não sei se há uma diferença de desempenho embora)
Cornelis
1
Esta é a melhor resposta IMO.
Loolooii 22/03
1
A compilação das respostas @pbaron e @Cornelis funciona melhor. O que eu adicionei é um código Cornelis dentro função de segundo 'click' (logo antes $(this).popover('toggle');parte Então, se você tiver vários objetos 'pop-up de marcadores', clicando em cada um vai fechar os outros..
alekwisnia
2
O único problema com isso é que o popover ainda está lá, apenas oculto. Assim, por exemplo, se você tiver links na popover, poderá passar o cursor onde costumava estar e ainda fazer com que o cursor mude sobre esses links.
Glacials
48

Eu tinha uma necessidade semelhante e encontrei esta grande extensão do Popover Bootstrap do Twitter de Lee Carmichael, chamada BootstrapX - clickover . Ele também tem alguns exemplos de uso aqui . Basicamente, ele mudará a popover para um componente interativo que será fechado quando você clicar em outro lugar na página ou em um botão fechar dentro da popover. Isso também permitirá que vários popovers sejam abertos ao mesmo tempo e vários outros recursos interessantes.

O plug-in pode ser encontrado aqui .

Exemplo de uso

<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();
Miika L.
fonte
1
Isso é realmente ótimo. Super fácil.
Doug
Excellent plugin! Obrigado pelo link.
Matt Wilson
1
Apenas tentei e funciona muito bem. Foi tão fácil quanto apenas alterar o rel de um popover existente de "popover" para "clickover".
Dmase05
Executando no Bootstrap v2.3.1, sem problemas.
Kevin Dewalt
37

A solução aceita me deu alguns problemas (clicar no elemento '.popup-marker' do popover aberto fazia com que os popovers não funcionassem mais tarde). Eu vim com essa outra solução que funciona perfeitamente para mim e é bastante simples (estou usando o 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');
    }
});

ATUALIZAÇÃO: Esse código também funciona com o Bootstrap 3!

RayOnAir
fonte
1
Esta é uma otima soluçao. Obrigado.
Gavin
1
Boa solução. Por que você não usar if (!$(e.target).is('.popup-marker') && !$(e.target).parents('.popover').length > 0)dessa forma o pop-up não vai fechar, mesmo que seja tem conteúdo html
ykay diz Reintegrar Monica
2
Ou melhorif (!$(e.target).is('.popup-marker') && $(e.target).closest('.popover').length === 0)
fabdouglas
19

leia "Ignorar no próximo clique" aqui http://getbootstrap.com/javascript/#popovers

Você pode usar o gatilho de foco para descartar popovers no próximo clique, mas precisa usar a <a>tag, não a <button>tag, e também deve incluir um tabindexatributo ...

Exemplo:

<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>
Andrej Sramko
fonte
2
A pergunta afirmava que ele não queria que fosse descartado se o clique estivesse no popover. Isso descartá-lo com qualquer clique em qualquer lugar.
Fred
1
Adicionar data-trigger = "focus" impediu o lançamento de meus popovers até eu ler esta postagem e adicionar o atributo tabindex. Agora funciona!
precisa saber é o seguinte
2
Para obter informações, isso também funciona tooltip, mesmo que não esteja claramente mencionado no documento real.
21815 AlexB
7

Todas as respostas existentes são bastante fracas, pois dependem da captura de todos os eventos do documento e da localização de popovers ativos ou da modificação da chamada para .popover().

Uma abordagem muito melhor é escutar show.bs.popovereventos no corpo do documento e reagir de acordo. Abaixo está o código que fechará popovers quando o documento for clicado ou escpressionado, vinculando apenas os ouvintes de eventos quando popovers forem mostrados:

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);
}
David Wolever
fonte
+1 Esta é a solução mais limpa e extensível. Se você estiver usando uma estrutura como o backbone, basta despejar isso no seu código de inicialização e ele cuidará do tratamento dos popovers.
9788 JohnPerfil
Essa resposta também adiciona preocupações de desempenho e permite lidar com HTML mais complexo dentro do popover.
Ricardo
Ótima solução; foi capaz de colocá-lo em um método de reação com bastante facilidade. Uma sugestão, adicione $(event.target).data("bs.popover").inState.click = false;à função onPopoverHide para que você não precise clicar duas vezes para reabrir após o fechamento.
sco_tt
Curioso, se você pudesse fazer um violino disso com dois pop-ups. No meu aplicativo, quando implementei seu código, pude clicar em pop-up para pop-up e vários apareceram; em seguida, clicar no 'corpo' removeu apenas o último exibido.
Terry
2

Por alguma razão, nenhuma das outras soluções aqui funcionou para mim. No entanto, após muita solução de problemas, finalmente cheguei a esse método que funciona perfeitamente (pelo menos para mim).

$('html').click(function(e) {
  if( !$(e.target).parents().hasClass('popover') ) {
    $('#popover_parent').popover('destroy');
  }
});

No meu caso, eu estava adicionando um popover a uma tabela e posicionando-o absolutamente acima / abaixo do tdque foi clicado. A seleção da tabela foi tratada pelo jQuery-UI Selectable, portanto, não tenho certeza se isso estava interferindo. No entanto, sempre que eu clicava dentro do popover, meu manipulador de cliques, que $('.popover')nunca segmentava, funcionava e a manipulação de eventos sempre era delegada ao$(html) manipulador de cliques. Eu sou bastante novo para JS, então talvez eu só esteja faltando alguma coisa?

Enfim, espero que isso ajude alguém!

moollaza
fonte
BTW Não tenho certeza se isso importa, mas usei esse método para o Bootstrap 2. Suponho que funcionará no Bootstrap 3, mas não o confirmei.
moollaza
2

Dou todas as minhas âncoras para a classe activate_popover. Ativo todos de uma só vez onload

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

para obter a funcionalidade de clique fora do trabalho que eu uso (no script de café):

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

O que funciona perfeitamente bem com o bootstrap 2.3.1

Bert-Jan Steerneman
fonte
Isso funcionou para mim, exceto que eu tive que me livrar da .prev()primeira ifcláusula. Estou usando o Bootstrap 3.2.0.2, talvez haja uma diferença? Além disso, você pode simplesmente deixar de fora a segunda ifcláusula inteira se desejar poder abrir vários pop-ups ao mesmo tempo. Basta clicar em qualquer lugar que não seja um elemento de ativação de popover (classe 'ativar-popover' neste exemplo) para fechar todos os popovers abertos. Funciona bem!
Andrew Swihart 19/10/2014
2

Embora existam muitas soluções aqui, eu gostaria de propor a minha também, não sei se existe alguma solução lá em cima que resolva tudo, mas tentei 3 delas e elas tiveram problemas, como clicar em na popover auto torna esconder, outros que se eu tivesse outro popover botões clicado ambos / múltiplas popovers ainda parece (como na solução selecionada), Como sempre, este um fixo tudo

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();
});
Roshdy
fonte
2

Eu definiria o foco para o pop-over recém-criado e o removeria no desfoque. Dessa forma, não é necessário verificar qual elemento do DOM foi clicado e o pop-over pode ser clicado e também selecionado: ele não perderá o foco e não desaparecerá.

O código:

    $('.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');
    });
Luca Vizzi
fonte
1

Aqui está a solução que funcionou muito bem para mim, se puder ajudar:

/**
* 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;
        }        
    });
});
Gilles Hemmerlé
fonte
1

Aqui está a minha solução, para o que vale a pena:

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

  });
});
nates
fonte
1

Eu tive algum problema para fazê-lo funcionar no bootstrap 2.3.2. Mas eu deslizei desta maneira:

$(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
    });
});
oBo
fonte
1

tweaked @David Wolever ligeiramente:

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);
}
Lee Gary
fonte
1

Essa pergunta também foi feita aqui e minha resposta fornece não apenas uma maneira de entender os métodos de passagem do jQuery DOM, mas duas opções para lidar com o fechamento de popovers clicando fora.

Abra vários popovers de uma só vez ou um popover de cada vez.

Além disso, esses pequenos trechos de código podem lidar com o fechamento de botões que contêm ícones!

https://stackoverflow.com/a/14857326/1060487

mattdlockyer
fonte
1

Este funciona como um encanto e eu o uso.

Ele abrirá a janela pop-up quando você clicar e, se você clicar novamente, ela será fechada; também, se você clicar fora dela, a janela popover será fechada.

Isso também funciona com mais de 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();
});
Patrick Nogueira
fonte
Este é o único que funcionou para mim. Bootstrap 3.20. Obrigado.
Telegard 21/10
1

Outra solução, abordou o problema que tive ao clicar em descendentes do popover:

$(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');
    }
});
Fernando Caraballo
fonte
0

Eu faço isso como abaixo

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

Espero que isto ajude!

foxybagga
fonte
0

Se você está tentando usar o popover de inicialização do twitter com pjax, isso funcionou para mim:

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);
});
keruilin
fonte
0

@ RayOnAir, tenho o mesmo problema com as soluções anteriores. Também estou perto da solução @RayOnAir. Uma coisa que melhorou é fechar popover já aberto quando clicar em outro marcador de popover. Então, meu código é:

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;
  }
});
msa.im
fonte
0

Eu achei que essa era uma solução modificada da sugestão do pbaron acima, porque a solução dele ativou o popover ('hide') em todos os elementos com a classe 'popup-marker'. No entanto, quando você usa popover () para conteúdo html em vez do conteúdo de dados, como faço abaixo, qualquer clique dentro desse pop-up html realmente ativa o popover ('hide'), que fecha imediatamente a janela. Este método abaixo itera através de cada elemento .popup-marker e descobre primeiro se o pai está relacionado ao ID do .popup-marker que foi clicado e, nesse caso, não o oculta. Todas as outras divs estão ocultas ...

        $(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();
            });
        });
David
fonte
0

Eu vim com isso:

Meu cenário incluía mais popovers na mesma página, e ocultá-los apenas os tornava invisíveis e, por isso, não foi possível clicar nos itens por trás do popover. A idéia é marcar o link popover específico como 'ativo' e, em seguida, você pode simplesmente 'alternar' o popover ativo. Fazer isso fechará a popover completamente.

$('.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"
Adi Nistor
fonte
0

Eu estava tentando criar uma solução simples para um problema simples. As postagens acima são boas, mas muito complicadas para um problema simples. Então eu fiz uma coisa simples. Acabei de adicionar um botão Fechar. É perfeito para mim.

            $(".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;
    }
Mohammad Kashif
fonte
0

Eu gosto disso, simples, mas eficaz ..

var openPopup;

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

    }
    openPopup=this;
});
gstarr
fonte
0

Adicione btn-popoverclasse ao seu botão / link popover que abre a popover. Este código fechará os popovers ao clicar fora dele.

$('body').on('click', function(event) {
  if (!$(event.target).closest('.btn-popover, .popover').length) {
    $('.popover').popover('hide');
  }
});
Tobias Mühl
fonte
0

Uma solução ainda mais fácil, basta percorrer todos os popovers e ocultar, se não 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');
        }
    });
});
inostia
fonte
0
$('.popForm').popover();

$('.conteneurPopForm').on("click",".fermePopover",function(){
    $(".popForm").trigger("click");
});

Para ser claro, basta acionar a popover

poeta
fonte
0

Isso deve funcionar no Bootstrap 4:

$("#my-popover-trigger").popover({
  template: '<div class="popover my-popover-content" role="tooltip"><div class="arrow"></div><div class="popover-body"></div></div>',
  trigger: "manual"
})

$(document).click(function(e) {
  if ($(e.target).closest($("#my-popover-trigger")).length > 0) {
    $("#my-popover-trigger").popover("toggle")
  } else if (!$(e.target).closest($(".my-popover-content")).length > 0) {
    $("#my-popover-trigger").popover("hide")
  }
})

Explicação:

  • A primeira seção apresenta o popover conforme os documentos: https://getbootstrap.com/docs/4.0/components/popovers/
  • O primeiro "se" na segunda seção verifica se o elemento clicado é descendente de # my-popover-trigger. Se isso for verdade, alterna o popover (ele lida com o clique no gatilho).
  • O segundo "se" na segunda seção verifica se o elemento clicado é um descendente da classe de conteúdo popover que foi definida no modelo init. Se não for, isso significa que o clique não estava dentro do conteúdo do popover e o popover pode ser oculto.
Bart Blast
fonte
Você poderia elaborar seu código? Adicione alguma explicação ao que você está fazendo?
Death Waltz
@DeathWaltz Acabei de adicionar uma explicação na resposta.
Bart Blast
-1

Tente em data-trigger="focus"vez de "click".

Isso resolveu o problema para mim.

Hannes
fonte