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?


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 :-)


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

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();

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!


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>

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

+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!


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


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

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

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

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

  });
});

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

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

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


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

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

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!


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

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

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

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"

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

0

Eu gosto disso, simples, mas eficaz ..

var openPopup;

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

    }
    openPopup=this;
});

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

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

0
$('.popForm').popover();

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

Para ser claro, basta acionar a popover


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.

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.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.