130 votes

Comment faire vivre les popovers Bootstrap lorsqu'ils sont survolés ?

J'utilise un popover Bootstrap pour créer une carte de survol affichant des informations sur l'utilisateur, et je la déclenche au passage de la souris sur un bouton. Je veux garder cette popover vivante pendant que la popover elle-même est survolée, mais elle disparaît dès que l'utilisateur cesse de survoler le bouton. Comment puis-je faire cela ?

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

$(document).on('mouseover', '#example', function(){
    $('#example').popover('show');
});

$(document).on('mouseleave', '#example', function(){
    $('#example').popover('hide');
});

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.js"></script>
<script src="https://unpkg.com/@popperjs/core@2"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"/>

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

9voto

Voici une solution que j'ai conçue et qui semble bien fonctionner, tout en vous permettant d'utiliser la mise en œuvre normale de Bootstrap pour activer tous les popovers.

Violon original : https://jsfiddle.net/eXpressive/hfear592/

Porté à cette question :

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

7voto

hoektoe Points 31

C'est ce que j'ai fait avec le popover bootstrap avec l'aide d'autres éléments sur le net. Il obtient dynamiquement le titre et le contenu des différents produits affichés sur le site. Chaque produit ou popover a un identifiant unique. Le popover disparaît quand on quitte le produit ( $this .pop) ou le popover. Timeout est utilisé pour afficher la popover jusqu'à la sortie du produit au lieu de la 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();
    };

5voto

forumulator Points 484

Je suis d'accord que le meilleur moyen est d'utiliser celui donné par : David Chase Cu Ly, et d'autres, que le moyen le plus simple de le faire est d'utiliser la fonction container: $(this) comme suit :

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

Je tiens à souligner ici que le popover dans ce cas héritera de toutes les propriétés de l'élément actuel . Ainsi, par exemple, si vous faites cela pour une .btn élément(bootstrap), vous ne pourrez pas sélectionner le texte à l'intérieur de la fenêtre contextuelle. . Je voulais juste noter que j'ai passé pas mal de temps à me casser la tête sur ce sujet.

1voto

user1993198 Points 1

La réponse de Vikas fonctionne parfaitement pour moi, ici j'ajoute aussi le support pour le délai (montrer / cacher).

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

Aussi, s'il vous plaît, faites attention à ce que j'ai changé :

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

avec :

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

pour qu'il se réfère exactement à ce popover ouvert, et pas à un autre (puisque maintenant, grâce au délai, plus d'un popover pourrait être ouvert en même temps)

1voto

Rubens Mariuzzo Points 6022

La réponse choisie travaux mais échouera si le popover est initialisé avec l'option body comme conteneur.

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

Une solution basée sur la réponse choisie est le code suivant qui doit être placé avant d'utiliser le 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);
            });
        })
    }
};

Le changement est minime en utilisant self.$tip au lieu de parcourir le DOM en s'attendant à ce que le popover soit toujours un frère de l'élément.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X