¿Cómo puedo mantener vivo el popover bootstrap mientras el popover está flotando?


Estoy usando el popover de twitter boostrap para crear una tarjeta de hover para mostrar información del usuario, y estoy activando el popover en mouseover check jsfiddle aquí. Quiero mantener vivo este popover mientras se cierne sobre él.

<a href="#" id="example" class="btn btn-danger" rel="popover" >hover for popover</a>

$('#example').popover({
        html : true,
        trigger : 'manual',
        content : function() {
            return '<div class="box"></div>';
        }
    });
$(document).on('mouseover', '#example', function(){
    $('#example').popover('show');
});
$(document).on('mouseleave', '#example', function(){
    $('#example').popover('hide');
});

Usted puede pensar en el trabajo de facebook hover card. Quiero hacerlo de la misma manera. ¿Cómo puedo hacer esto?

Author: Doorknob, 2013-04-13

16 answers

Ver este código de trabajo en Plunker

Pequeña modificación (de la solución proporcionada por vikas) para adaptarse a mi caso de uso.
1. Abrir popover en el evento hover para el botón popover
2. Mantenga el popover abierto al pasar el cursor sobre el popover box
3. Cierre la ventana emergente en mouseleave para el botón emergente o el cuadro emergente.

$('.pop').popover({
    trigger: 'manual',
    html: true,
    animation: false
})
.on('mouseenter', function () {
    var _this = this;
    $(this).popover('show');
    $('.popover').on('mouseleave', function () {
        $(_this).popover('hide');
    });
}).on('mouseleave', function () {
    var _this = this;
    setTimeout(function () {
        if (!$('.popover:hover').length) {
            $(_this).popover('hide');
        }
    }, 300);
});

Juega con él en Plunker

 127
Author: OkezieE,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-18 09:46:16

He venido tras otra solución a esto...aquí está el código

    $('.selector').popover({
        html: true,
        trigger: 'manual',
        container: $(this).attr('id'),
        placement: 'top',
        content: function () {
            $return = '<div class="hover-hovercard"></div>';
        }
    }).on("mouseenter", function () {
        var _this = this;
        $(this).popover("show");
        $(this).siblings(".popover").on("mouseleave", function () {
            $(_this).popover('hide');
        });
    }).on("mouseleave", function () {
        var _this = this;
        setTimeout(function () {
            if (!$(".popover:hover").length) {
                $(_this).popover("hide")
            }
        }, 100);
    });
 74
Author: vikas devde,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-08-01 14:43:44

Aquí está mi opinión: http://jsfiddle.net/WojtekKruszewski/Zf3m7/22/

A veces, mientras mueve el ratón del desencadenador emergente al contenido emergente real diagonalmente, pasa el cursor sobre los elementos de abajo. Quería manejar este tipo de situaciones – siempre y cuando llegues a contenido emergente antes de que se inicie el tiempo de espera, estás a salvo (el popover no desaparecerá). Requiere la opción delay.

Este hack básicamente anula la función Popover leave, pero llama al original (que inicia el temporizador para ocultar el popover). Luego adjunta un oyente único a mouseenter elementos de contenido emergente.

Si el ratón entra en la ventana emergente, el temporizador se borra. A continuación, se convierte en escucha mouseleave en el popover y si se activa, llama a la función de salida original para que pueda iniciar ocultar temporizador.

var originalLeave = $.fn.popover.Constructor.prototype.leave;
$.fn.popover.Constructor.prototype.leave = function(obj){
  var self = obj instanceof this.constructor ?
    obj : $(obj.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type)
  var container, timeout;

  originalLeave.call(this, obj);

  if(obj.currentTarget) {
    container = $(obj.currentTarget).siblings('.popover')
    timeout = self.timeout;
    container.one('mouseenter', function(){
      //We entered the actual popover – call off the dogs
      clearTimeout(timeout);
      //Let's monitor popover content instead
      container.one('mouseleave', function(){
        $.fn.popover.Constructor.prototype.leave.call(self, self);
      });
    })
  }
};
 28
Author: Wojtek Kruszewski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-03-24 13:15:03

Usé el trigger set a hover y le di el container set a #element y finalmente añadí una colocación de box a right.

Esta debería ser tu configuración:

$('#example').popover({
    html: true,
    trigger: 'hover',
    container: '#example',
    placement: 'right',
    content: function () {
        return '<div class="box"></div>';
    }
});

Y #example css necesita position:relative; compruebe el jsfiddle a continuación:

Https://jsfiddle.net/9qn6pw4p/1 /

Editado

Este violín tiene ambos enlaces que funcionan sin problemas http://jsfiddle.net/davidchase03/FQE57/4 /

 10
Author: David Chase,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-25 09:23:34

Creo que una manera fácil sería esta:

$('.popover').each(function () {
                    var $this = $(this);
                    $this.popover({
                        trigger: 'hover',
                        content: 'Content Here',
                        container: $this
                    })
                });

De esta manera, el popover se crea dentro del propio elemento de destino. así que cuando mueve el ratón sobre la ventana emergente, todavía está sobre el elemento. Bootstrap 3.3.2 funciona bien con esto. La versión anterior puede tener algunos problemas con la animación, por lo que es posible que desee desactivar "animation:false"

 7
Author: Cu Lý,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-01-27 07:44:48

Esto es lo que hice con bootstrap popover con la ayuda de otros bits alrededor de la red. Dinámicamente obtiene el título y el contenido de los diversos productos que se muestran en el sitio. Cada producto o popover obtiene un id único. Popover desaparecerá al salir del producto (this this .pop) o el popover. Tiempo de espera se utiliza donde se mostrará el popover hasta la salida a través de producto en lugar de popover.

$(".pop").each(function () {
        var $pElem = $(this);
        $pElem.popover(
            {
                html: true,
                trigger: "manual",
                title: getPopoverTitle($pElem.attr("id")),
                content: getPopoverContent($pElem.attr("id")),
                container: 'body',
                animation:false
            }
        );
    }).on("mouseenter", function () {
        var _this = this;
        $(this).popover("show");
        console.log("mouse entered");
        $(".popover").on("mouseleave", function () {
            $(_this).popover('hide');
        });
    }).on("mouseleave", function () {
        var _this = this;
        setTimeout(function () {
            if (!$(".popover:hover").length) {
                $(_this).popover("hide");
            }
        }, 100);
    });
    function getPopoverTitle(target) {
        return $("#" + target + "_content > h3.popover-title").html();
    };

    function getPopoverContent(target) {
        return $("#" + target + "_content > div.popover-content").html();
    };
 6
Author: hoektoe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-10-11 07:37:47

Aquí hay una solución que ideé que parece funcionar bien al tiempo que le permite usar la implementación de Bootstrap normal para activar todos los popovers.

Violín original: https://jsfiddle.net/eXpressive/hfear592 /

Portado a esta pregunta:

<a href="#" id="example" class="btn btn-danger" rel="popover" >hover for popover</a>

$('#example').popover({
    html : true,
    trigger : 'hover',
    content : function() {
        return '<div class="box"></div>';
    }
}).on('hide.bs.popover', function () {
    if ($(".popover:hover").length) {
      return false;
    }                
}); 

$('body').on('mouseleave', '.popover', function(){
    $('.popover').popover('hide');
});
 4
Author: eXpressiveDesign,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-08-24 15:29:30

Vikas answer funciona perfectamente para mí, aquí también añado soporte para el retraso (mostrar / ocultar).

var popover = $('#example');
var options = {
    animation : true,
    html: true,
    trigger: 'manual',
    placement: 'right',
    delay: {show: 500, hide: 100}
};   
popover
    .popover(options)
    .on("mouseenter", function () {

        var t = this;
        var popover = $(this);    
        setTimeout(function () {

            if (popover.is(":hover")) {

                popover.popover("show");
                popover.siblings(".popover").on("mouseleave", function () {
                    $(t).popover('hide');
                });
            }
        }, options.delay.show);
    })
    .on("mouseleave", function () {
        var t = this;
        var popover = $(this);

        setTimeout(function () {
            if (popover.siblings(".popover").length && !popover.siblings(".popover").is(":hover")) {
                $(t).popover("hide")
            }
        }, options.delay.hide);
    });     

También por favor preste atención cambié:

if (!$(".popover:hover").length) {

Con:

if (popover.siblings(".popover").length && !popover.siblings(".popover").is(":hover")) {

Para que haga referencia exactamente a ese popover abierto, y no a cualquier otro (ya que ahora, a través del retraso, más de 1 podría abrirse al mismo tiempo)

 1
Author: user1993198,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-01-08 04:18:55

La respuesta elegida funciona pero fallará si la ventana emergente se inicializa con body como contenedor.

$('a').popover({ container: 'body' });

Una solución basada en la respuesta elegida es el siguiente código que debe colocarse antes de usar el popover.

var originalLeave = $.fn.popover.Constructor.prototype.leave;
$.fn.popover.Constructor.prototype.leave = function(obj) {
    var self = obj instanceof this.constructor ? obj : $(obj.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type);
    originalLeave.call(this, obj);

    if (obj.currentTarget) {
        self.$tip.one('mouseenter', function() {
            clearTimeout(self.timeout);
            self.$tip.one('mouseleave', function() {
                $.fn.popover.Constructor.prototype.leave.call(self, self);
            });
        })
    }
};

El cambio es mínimo usando self.$tip en lugar de atravesar el DOM esperando que el popover sea siempre un hermano del elemento.

 1
Author: Rubens Mariuzzo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-02-25 23:36:48

Simple:)

$('[data-toggle="popover"]').popover( { "container":"body", "trigger":"focus", "html":true });
$('[data-toggle="popover"]').mouseenter(function(){
    $(this).trigger('focus');
});
 1
Author: edmc73,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-23 14:32:17

Lo mismo para las descripciones emergentes:

Para mí, la siguiente solución funciona porque no agrega escuchas de eventos en cada 'mouseenter' y es posible volver a colocar el cursor sobre el elemento tooltip que mantiene vivo el tooltip.

$ ->

  $('.element').tooltip({
    html: true,
    trigger: 'manual'
  }).
  on 'mouseenter', ->
    clearTimeout window.tooltipTimeout
    $(this).tooltip('show') unless $('.tooltip:visible').length > 0
  .
  on 'mouseleave', ->
    _this = this
    window.tooltipTimeout = setTimeout ->
      $(_this).tooltip('hide')
    , 100

$(document).on 'mouseenter', '.tooltip', ->
  clearTimeout window.tooltipTimeout

$(document).on 'mouseleave', '.tooltip', ->
  trigger = $($(this).siblings('.element')[0])
  window.tooltipTimeout = setTimeout ->
    trigger.tooltip('hide')
  , 100
 0
Author: phlppn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-11-12 10:13:34

Esta solución funcionó bien para mí: (ahora es a prueba de balas); -)

function enableThumbPopover() {
    var counter;

    $('.thumbcontainer').popover({
        trigger: 'manual',
        animation: false,
        html: true,
        title: function () {
            return $(this).parent().find('.thumbPopover > .title').html();
        },
        content: function () {
            return $(this).parent().find('.thumbPopover > .body').html();
        },
        container: 'body',
        placement: 'auto'
    }).on("mouseenter",function () {
        var _this = this; // thumbcontainer

        console.log('thumbcontainer mouseenter')
        // clear the counter
        clearTimeout(counter);
        // Close all other Popovers
        $('.thumbcontainer').not(_this).popover('hide');

        // start new timeout to show popover
        counter = setTimeout(function(){
            if($(_this).is(':hover'))
            {
                $(_this).popover("show");
            }
            $(".popover").on("mouseleave", function () {
                $('.thumbcontainer').popover('hide');
            });
        }, 400);

    }).on("mouseleave", function () {
        var _this = this;

        setTimeout(function () {
            if (!$(".popover:hover").length) {
                if(!$(this).is(':hover'))
                {
                    $(_this).popover('hide');
                }
            }
        }, 200);
    });
}
 0
Author: Johannes Ferner,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-09 07:43:10
        $(function() {
            $("[data-toggle = 'popover']").popover({
                placement: 'left',
                html: true,
                trigger: "  focus",
            }).on("mouseenter", function() {
                var _this = this;
                $(this).popover("show");
                $(this).siblings(".popover").on("mouseleave", function() {
                    $(_this).popover('hide');
                });
            }).on("mouseleave", function() {
                var _this = this;
                setTimeout(function() {
                    if (!$(".popover:hover").length) {
                        $(_this).popover("hide")
                    }
                }, 100);
            });
        }); 
 0
Author: Dinesh Sarak,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-09 21:15:12

Estoy de acuerdo en que la mejor manera es usar la dada por: David Chase, Cu Ly, y otros que la forma más sencilla de hacer esto es usar la propiedad container: $(this) de la siguiente manera:

$(selectorString).each(
  var $this = $(this);
  $this.popover({
    html: true,
    placement: "top",
    container: $this,
    trigger: "hover",
    title: "Popover",
    content: "Hey, you hovered on element"
  });
);

Quiero señalar aquí que el popover en este caso heredará todas las propiedades del elemento actual . Así, por ejemplo, si haces esto para un elemento .btn (bootstrap), no podrás seleccionar texto dentro de la ventana emergente. Sólo quería grabar que desde que pasé bastante tiempo golpeándome la cabeza con esto.

 0
Author: forumulator,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-06-30 05:52:46

Encontré que el mouseleave no se disparará cuando sucedan cosas extrañas, como que el enfoque de la ventana cambia repentinamente, luego el usuario regresa al navegador. En casos como ese, mouseleave nunca se disparará hasta que el cursor pase y deje el elemento de nuevo.

Esta solución que se me ocurrió se basa en mouseenter en el objeto window, por lo que desaparece cuando el ratón se mueve a cualquier otro en la página.

Esto fue diseñado para funcionar con tener múltiples elementos en la página que se activarán (como en una tabla).

var allMenus = $(".menus");
allMenus.popover({
    html: true,
    trigger: "manual",
    placement: "bottom",
    content: $("#menuContent")[0].outerHTML
}).on("mouseenter", (e) => {
    allMenus.not(e.target).popover("hide");
    $(e.target).popover("show");
    e.stopPropagation();
}).on("shown.bs.popover", () => {
    $(window).on("mouseenter.hidepopover", (e) => {
        if ($(e.target).parents(".popover").length === 0) {
            allMenus.popover("hide");
            $(window).off("mouseenter.hidepopover");
        }
    });
});
 0
Author: Gabriel Luci,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-02 01:58:13

Será más flexible con hover():

$(".my-popover").hover(
    function() {  // mouse in event
        $this = $(this);
        $this.popover({
            html: true,
            content: "Your content",
            trigger: "manual",
            animation: false
            });
        $this.popover("show");
        $(".popover").on("mouseleave", function() {
            $this.popover("hide");
        });
    },
    function() {  // mouse out event
        setTimeout(function() {
            if (!$(".popover:hover").length) {
                $this.popover("hide");
            }
        }, 100);
    } 
)
 0
Author: Grey Li,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-15 07:27:04