¿Cómo puedo cerrar un popover de Bootstrap de Twitter con un clic desde cualquier otro lugar de la página?

155

Actualmente estoy usando popovers con Twitter Bootstrap, iniciado así:

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

Como puede ver, se activan manualmente, y al hacer clic en .popup-marker (que es un div con una imagen de fondo) alterna un popover. Esto funciona muy bien, pero me gustaría poder cerrar el popover con un clic en cualquier otro lugar de la página (¡pero no en el popover mismo!).

He intentado algunas cosas diferentes, incluidas las siguientes, pero sin resultados que mostrar:

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

¿Cómo puedo cerrar el popover con un clic en cualquier otro lugar de la página, pero no con un clic en el popover?

Travis Northcutt
fuente
Hm, creo que funcionaría ... ¿tienes un enlace a esto en línea por casualidad?
thatryan

Respuestas:

102

Suponiendo que solo se puede ver un popover en cualquier momento, puede usar un conjunto de banderas para marcar cuando hay un popover visible, y solo luego ocultarlos.

Si configura el detector de eventos en el cuerpo del documento, se activará cuando haga clic en el elemento marcado con 'marcador emergente'. Entonces tendrás que llamarstopPropagation() al objeto de evento. Y aplique el mismo truco al hacer clic en el popover.

A continuación hay un código JavaScript que funciona que hace esto. Utiliza 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/

La única advertencia es que no podrás abrir 2 popovers al mismo tiempo. Pero creo que eso sería confuso para el usuario, de todos modos :-)

Radu Cugut
fuente
1
Al hacer clic en el popover en sí mismo, jsfiddle hace que el popover se oculte, no exactamente lo que tnorthcutt preguntó.
Jonathon Hill
1
@RaduCugut es una gran solución. Pero tiene un error. Haga clic una vez en zzzzz y aparecerá el popover. Ahora haga clic una vez en el fondo blanco. La ventana emergente desaparece. Ahora haga clic nuevamente en el fondo blanco. Y ahora haga clic nuevamente en zzzz y no funciona. : - |
Houman
1
@Kave tienes razón, he modificado el violín y la respuesta para corregir esto. jsfiddle.net/AFffL/177
Radu Cugut
3
¿Por qué no simplemente ejecutar $ ('. Popup-marker'). Popover ('hide') (para ocultarlos todos) antes de $ (this) .popover ('show'), lo que elimina la necesidad de cualquier variable isVisible y clickedAway?
Nathan Hangen
1
Esta solución me dio algunos problemas (al hacer clic en el elemento '.popup-marker' del popover abierto, los popovers no funcionaron después). Se me ocurrió otra solución (publicada a continuación) que funcionó para mí y parece más simple (estoy usando Bootstrap 2.3.1).
RayOnAir
76

Esto es aún más 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
fuente
Convenido. Y al menos para mí, esa es la forma correcta de hacerlo. La primera opción parece ser una "solución rápida".
Denis Lins el
44
Deseaba usar esto, pero por alguna razón no funcionó. Los eventos de clic nunca llegaron htmla causa de e.stopPropagation();su lugar he usado algo parecido a $('.popup-marker').on('show', function(event) { $('.popup-marker').filter(function(index, element) { return element != event.target; }).popover('hide'); });lo que hizo el buen trabajo también (no sé si hay una diferencia de rendimiento sin embargo)
Cornelis
1
Esta es la mejor respuesta de la OMI.
Loolooii
1
La compilación de las respuestas de @pbaron y @Cornelis funciona mejor. Lo que he añadido es el código Cornelis dentro segunda función de 'clic' (justo antes de $(this).popover('toggle');la parte Entonces, si tiene varios objetos 'popup-marcadoras', haciendo clic en cada uno se cerrará los otros..
alekwisnia
2
El único problema con esto es que el popover todavía está allí, simplemente oculto. Entonces, por ejemplo, si tiene enlaces en el popover, puede pasar el cursor donde solía estar y aún así cambiar el cursor sobre esos enlaces.
Glaciales
48

Tenía una necesidad similar, y encontré esta pequeña gran extensión del Twitter Bootstrap Popover de Lee Carmichael, llamada BootstrapX - clickover . Él también tiene algunos ejemplos de uso aquí . Básicamente, cambiará el popover a un componente interactivo que se cerrará cuando haga clic en otra parte de la página, o en un botón de cierre dentro del popover. Esto también permitirá múltiples popovers abiertos a la vez y un montón de otras características agradables.

El complemento se puede encontrar aquí .

Ejemplo 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.
fuente
1
Esto es realmente genial Muy facil.
Doug
Excelente complemento! Gracias por el enlace.
Matt Wilson
1
Solo le di una oportunidad y funciona muy bien. Fue tan fácil como cambiar el relé de un popover existente de "popover" a "clickover".
Dmase05 12/12/12
Se ejecuta en Bootstrap v2.3.1, sin problemas.
Kevin Dewalt
37

La solución aceptada me dio algunos problemas (al hacer clic en el elemento '.popup-marker' del popover abierto, los popovers no funcionaron después). Se me ocurrió esta otra solución que funciona perfectamente para mí y es bastante simple (estoy usando 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');
    }
});

ACTUALIZACIÓN: ¡Este código también funciona con Bootstrap 3!

RayOnAir
fuente
1
Esta es una gran solución. Gracias.
Gavin
1
Buena solución. ¿Por qué no se utiliza if (!$(e.target).is('.popup-marker') && !$(e.target).parents('.popover').length > 0)de esa manera la ventana emergente no se cerrará incluso si se trata tiene contenido HTML
ykay dice Restablecer Mónica
2
O mejorif (!$(e.target).is('.popup-marker') && $(e.target).closest('.popover').length === 0)
fabdouglas
19

lea "Descartar en el siguiente clic" aquí http://getbootstrap.com/javascript/#popovers

Puede usar el desencadenador de foco para descartar los popovers en el siguiente clic, pero debe usar la <a>etiqueta, no la <button>etiqueta, y también debe incluir un tabindexatributo ...

Ejemplo:

<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
fuente
2
La pregunta decía que no quería que se descartara si el clic estaba en el popover. Esto lo descarta en cualquier clic en cualquier lugar.
Fred
1
Agregar data-trigger = "focus" detuvo el inicio de mis popovers hasta que leí esta publicación y agregué el atributo tabindex. ¡Ahora funciona!
PixelGraph
2
Para información, esto también funciona tooltip, incluso si no se menciona claramente en el documento real.
AlexB
7

Todas las respuestas existentes son bastante débiles, ya que dependen de capturar todos los eventos del documento y luego encontrar popovers activos o modificar la llamada a.popover() .

Un enfoque mucho mejor es escuchar los show.bs.popovereventos en el cuerpo del documento y luego reaccionar en consecuencia. A continuación se muestra un código que cerrará las ventanas emergentes cuando se haga clic en el documento o escse presione, solo vincula los oyentes de eventos cuando se muestran las ventanas emergentes:

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
fuente
+1 Esta es la solución más limpia y extensible. Si también está utilizando un marco como backbone, simplemente descargue esto en su código de inicialización y se encargará de manejar los popovers.
JohnP
Esta respuesta también agrega problemas de rendimiento y permite manejar HTML más complejo dentro del popover.
Ricardo
Gran solución; fue capaz de colocarlo en un método de reacción con bastante facilidad. Una sugerencia, agregue $(event.target).data("bs.popover").inState.click = false;a la función onPopoverHide para que no necesite hacer clic dos veces para volver a abrir después de cerrar.
sco_tt
Curioso si pudieras hacer un violín con dos ventanas emergentes. En mi aplicación cuando implementé su código, pude hacer clic en emergente a emergente y aparecieron múltiples, luego al hacer clic en el 'cuerpo' solo se eliminó el último que se muestra.
Terry
2

Por alguna razón, ninguna de las otras soluciones aquí funcionó para mí. Sin embargo, después de mucha resolución de problemas, finalmente llegué a este método que funciona perfectamente (al menos para mí).

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

En mi caso, estaba agregando un popover a una mesa y colocándolo absolutamente encima / debajo del tdque se hizo clic. La selección de la tabla fue manejada por jQuery-UI Seleccionable, así que no estoy seguro de si eso estaba interfiriendo. Sin embargo, cada vez que hacía clic dentro del popover, mi controlador de clics dirigido $('.popover')nunca funcionaba y el manejo de eventos siempre se delegaba al$(html) controlador de clics. Soy bastante nuevo en JS, ¿tal vez solo me falta algo?

De todos modos, ¡espero que esto ayude a alguien!

moollaza
fuente
Por cierto, no estoy seguro de si es importante, pero utilicé este método para Bootstrap 2. Supongo que funcionará para Bootstrap 3, pero no lo he confirmado.
moollaza
2

Doy todos mis anclas popovers la clase activate_popover. Los activo todos a la vez

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

para que funcione la funcionalidad de clics de distancia que uso (en 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')
)

Que funciona perfectamente bien con bootstrap 2.3.1

Bert-Jan Steerneman
fuente
Esto funcionó para mí, excepto que tuve que deshacerme de .prev()la primera ifcláusula. Estoy usando Bootstrap 3.2.0.2, ¿tal vez hay una diferencia? Además, puede omitir toda la segunda ifcláusula si desea poder abrir varias ventanas emergentes al mismo tiempo. Simplemente haga clic en cualquier lugar que no sea un elemento activador de popover (clase 'activar-popover' en este ejemplo) para cerrar todos los popovers abiertos. ¡Funciona genial!
Andrew Swihart
2

Aunque hay muchas soluciones aquí, me gustaría proponer la mía también, no sé si hay alguna solución que resuelva todo, pero probé 3 de ellas y tuvieron problemas, como hacer clic en el popover en sí mismo, lo oculta, otros que si tuviera otros botones de popover haciendo clic en ambos / múltiples popovers todavía aparecerían (como en la solución seleccionada), Sin embargo, este lo solucionó todo

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
fuente
2

Establecería el foco en la ventana emergente recién creada y la eliminaría en el desenfoque. De esa manera, no es necesario verificar en qué elemento del DOM se ha hecho clic y se puede hacer clic en el elemento emergente, y también se puede seleccionar: no perderá su foco y no desaparecerá.

El 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
fuente
1

Aquí está la solución que funcionó muy bien para mí, si puede ayudar:

/**
* 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é
fuente
1

Aquí está mi solución, por lo que vale:

// 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
fuente
1

Tuve algún problema para que funcione en bootstrap 2.3.2. Pero lo he querido de esta manera:

$(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
fuente
1

modificó ligeramente la solución de @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);
}
Lee Gary
fuente
1

Esta pregunta también se hizo aquí y mi respuesta proporciona no solo una forma de comprender los métodos de recorrido de jQuery DOM sino también 2 opciones para manejar el cierre de popovers haciendo clic afuera.

Abra múltiples popovers a la vez o un popover a la vez.

¡Además, estos pequeños fragmentos de código pueden manejar el cierre de botones que contienen iconos!

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

mattdlockyer
fuente
1

Este funciona como un encanto y lo uso.

Abrirá el popover cuando haga clic y, si vuelve a hacer clic, se cerrará; también, si hace clic fuera del popover, el popover se cerrará.

Esto también funciona con más 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
fuente
Este es el único que funcionó para mí. Bootstrap 3.20. Gracias.
Telegard
1

Otra solución, cubrió el problema que tuve al hacer clic en los descendientes del 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
fuente
0

Lo hago como abajo

$("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 esto ayude!

foxybagga
fuente
0

Si estás intentando usar popover bootstrap de twitter con pjax, esto funcionó para mí:

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
fuente
0

@RayOnAir, tengo el mismo problema con las soluciones anteriores. También me acerco a la solución @RayOnAir. Una cosa que mejoró es cerrar el popover ya abierto al hacer clic en otro marcador de popover. Entonces mi código es:

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
fuente
0

Encontré que esta es una solución modificada de la sugerencia de pbaron anterior, porque su solución activó el popover ('ocultar') en todos los elementos con la clase 'popup-marker'. Sin embargo, cuando usa popover () para contenido html en lugar del contenido de datos, como lo hago a continuación, cualquier clic dentro de esa ventana emergente html realmente activa el popover ('hide'), que cierra rápidamente la ventana. El siguiente método itera a través de cada elemento .popup-marker y descubre primero si el padre está relacionado con la identificación del marcador .popup en el que se hizo clic, y si es así, no lo oculta. Todos los demás divs están ocultos ...

        $(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
fuente
0

Se me ocurrió esto:

Mi escenario incluyó más popovers en la misma página, y ocultarlos los hizo invisibles y, por eso, no fue posible hacer clic en los elementos detrás del popover. La idea es marcar el enlace de popover específico como 'activo' y luego simplemente 'alternar' el popover activo. Hacerlo cerrará el popover por completo.

$('.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
fuente
0

Estaba tratando de hacer una solución simple para un problema simple. Las publicaciones anteriores son buenas pero muy complicadas para un problema simple. Entonces hice una cosa simple. Acabo de agregar un botón de cierre. Es perfecto para mi.

            $(".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
fuente
0

Me gusta esto, simple pero efectivo.

var openPopup;

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

    }
    openPopup=this;
});
gstarr
fuente
0

Agregue btn-popoverclase a su botón / enlace de popover que abre el popover. Este código cerrará los popovers al hacer clic fuera de él.

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

Una solución aún más fácil, solo recorre todos los popovers y oculta si no 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
fuente
0
$('.popForm').popover();

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

Para que quede claro, solo activa el popover

poete
fuente
0

Esto debería funcionar en 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")
  }
})

Explicación:

  • La primera sección inicia el popover según los documentos: https://getbootstrap.com/docs/4.0/components/popovers/
  • El primer "if" en la segunda sección verifica si el elemento seleccionado es descendiente de # my-popover-trigger. Si eso es cierto, alterna el popover (maneja el clic en el gatillo).
  • El segundo "si" en la segunda sección verifica si el elemento seleccionado es descendiente de la clase de contenido de popover que se definió en la plantilla de inicio. Si no es así, esto significa que el clic no estaba dentro del contenido de popover, y el popover puede ocultarse.
Bart Blast
fuente
¿Podría por favor elaborar su código? ¿Agregar alguna explicación a lo que estás haciendo?
Death Waltz
@DeathWaltz Acabo de agregar una explicación en la respuesta.
Bart Blast
-1

Intenta en data-trigger="focus"lugar de "click".

Esto resolvió mi problema.

Hannes
fuente