Comment puis-je garder les popovers Bootstrap en vie tout en étant survolé?

114

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

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

vikas devde
la source
tu veux garder quoi vivant? je survole le bouton et il est resté ouvert?
David Chase
lire la dernière ligne de la question
vikas devde

Réponses:

172

Testez avec l'extrait de code ci-dessous:

Petite modification (à partir de la solution fournie par vikas) pour convenir à mon cas d'utilisation.

  1. Ouvrir le popover lors de l'événement de survol pour le bouton popover
  2. Gardez le popover ouvert lorsque vous survolez la boîte popover
  3. Fermez le popover au départ de la souris pour le bouton popover ou la boîte popover.

$(".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);
  });
<!DOCTYPE html>
<html>

<head>
  <link data-require="bootstrap-css@*" data-semver="3.2.0" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" />
  <script data-require="jquery@*" data-semver="2.1.1" src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
  <script data-require="bootstrap@*" data-semver="3.2.0" src="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.js"></script>

  <link rel="stylesheet" href="style.css" />

</head>

<body>
  <h2 class='text-primary'>Another Great "KISS" Bootstrap Popover example!</h2>
  <p class='text-muted'>KISS = Keep It Simple S....</p>

  <p class='text-primary'>Goal:</p>
  <ul>
    <li>Open popover on hover event for the popover button</li>
    <li>Keep popover open when hovering over the popover box</li>
    <li>Close popover on mouseleave for either the popover button, or the popover box.</li>
  </ul>

  <button type="button" class="btn btn-danger pop" data-container="body" data-toggle="popover" data-placement="right" data-content="Optional parameter: Skip if this was not requested<br>                                    A placement group is a logical grouping of instances within a single Availability                                     Zone. Using placement groups enables applications to get the full-bisection bandwidth                                     and low-latency network performance required for tightly coupled, node-to-node                                     communication typical of HPC applications.<br>                                    This only applies to cluster compute instances: cc2.8xlarge, cg1.4xlarge, cr1.8xlarge, hi1.4xlarge and hs1.8xlarge.<br>                                    More info: <a href=&quot;http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/placement-groups.html&quot; target=&quot;_blank&quot;>Click here...</a>"
    data-original-title="" title="">
    HOVER OVER ME
    </button>
  <br><br>
  <button type="button" class="btn btn-info pop" data-container="body" data-toggle="popover" data-placement="right" data-content="Optional parameter: Skip if this was not requested<br>                                    A placement group is a logical grouping of instances within a single Availability                                     Zone. Using placement groups enables applications to get the full-bisection bandwidth                                     and low-latency network performance required for tightly coupled, node-to-node                                     communication typical of HPC applications.<br>                                    This only applies to cluster compute instances: cc2.8xlarge, cg1.4xlarge, cr1.8xlarge, hi1.4xlarge and hs1.8xlarge.<br>                                    More info: <a href=&quot;http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/placement-groups.html&quot; target=&quot;_blank&quot;>Click here...</a>"
    data-original-title="" title="">
    HOVER OVER ME... Again!
    </button><br><br>
  <button type="button" class="btn btn-success pop" data-container="body" data-toggle="popover" data-placement="right" data-content="Optional parameter: Skip if this was not requested<br>                                    A placement group is a logical grouping of instances within a single Availability                                     Zone. Using placement groups enables applications to get the full-bisection bandwidth                                     and low-latency network performance required for tightly coupled, node-to-node                                     communication typical of HPC applications.<br>                                    This only applies to cluster compute instances: cc2.8xlarge, cg1.4xlarge, cr1.8xlarge, hi1.4xlarge and hs1.8xlarge.<br>                                    More info: <a href=&quot;http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/placement-groups.html&quot; target=&quot;_blank&quot;>Click here...</a>"
    data-original-title="" title="">
    Okay one more time... !
    </button>
  <br><br>
  <p class='text-info'>Hope that helps you... Drove me crazy for a while</p>
  <script src="script.js"></script>
</body>

</html>

OkezieE
la source
Cela fonctionne parfaitement, j'ai remarqué qu'il y avait un manque ;dans votre seconde $(_this).popover("hide"). Mais merci, c'était si simple et propre!
scapegoat17
3
Cette réponse est incroyable. Fonctionne très bien sur BS3 à partir de mai 2015 ^^
dégénéré
1
Je l'ai utilisé dans un tableau et j'ai ajouté container: 'body'aux options car cela faisait bouger les cellules. Très bonne réponse!
Alexander Derck le
Le popover est masqué si vous le saisissez, puis revenez à l'élément déclencheur avant 300 ms. Pour résoudre ce problème, vérifiez si le popover et son déclencheur sont: survolez avant de le masquer dans setTimeout. J'utiliserais également setTimeout et la même approche sur la souris pour laisser le popover lui-même, pour corriger le scintillement.
rzb
Assurez-vous de définir animation:false pour corriger le scintillement - vérifiez le lien Plunker que j'ai ci-dessus. Cela fonctionne parfaitement pour moi.
OkezieE
84

Je suis venu après une autre solution à cela ... voici le code

    $('.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);
    });
vikas devde
la source
6
Il est important d'ajouter animation: falsesinon le fait de déplacer la souris sur le lien à plusieurs reprises le fera ne pas fonctionner correctement
jasop
5
J'ai une petite modification à votre code @vikas ( gist.github.com/Nitrodist/7913848 ). Il revérifie l'état après 50 ms afin qu'il ne reste pas bloqué ouvert. Autrement dit, il le revérifie en permanence toutes les 50 ms.
Nitrodist
2
Comment cela peut-il être adapté pour qu'il fonctionne sur les éléments en direct qui viennent d'être ajoutés au document?
williamsowen
28

Voici ma prise: http://jsfiddle.net/WojtekKruszewski/Zf3m7/22/

Parfois, en déplaçant la souris du déclencheur de popover vers le contenu de popover réel en diagonale , vous survolez les éléments ci-dessous. Je voulais gérer de telles situations - tant que vous atteignez le contenu popover avant le déclenchement du délai d'attente, vous êtes en sécurité (le popover ne disparaîtra pas). Cela nécessite une delayoption.

Ce hack remplace fondamentalement la leavefonction Popover , mais appelle l'original (qui démarre le minuteur pour masquer le popover). Ensuite, il attache un auditeur unique aux mouseenteréléments de contenu popover.

Si la souris entre dans le popover, la minuterie est effacée. Ensuite, il écoute mouseleavele popover et s'il est déclenché, il appelle la fonction de congé d'origine afin de pouvoir démarrer le minuteur de masquage.

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);
      });
    })
  }
};
Wojtek Kruszewski
la source
5
La recherche du conteneur peut être améliorée en utilisant De container = self.$tip;cette façon, le popover peut même être trouvé lorsque la containerpropriété est définie. Il y a un violon ici: jsfiddle.net/dennis_c/xJc65
dbroeks
3
@pferrel j'ai résolu ce problème dans mon fork du violon de @Wojtek_Kruszewski : jsfiddle.net/HugeHugh/pN26d voir la partie qui vérifie if (!thisTip.is(':visible'))avant d'appeler leoriginalShow()
H Dog
1
Si le popover est initialisé avec l'option, container: 'body',cette solution ne fonctionnera pas comme prévu. La variable containerdoit être remplacée par self.$tip. Vérifiez ma réponse pour plus de détails: stackoverflow.com/a/28731847/439427
Rubens Mariuzzo
1
Brillant. Cela fonctionne lorsque vous utilisez le paramètre «sélecteur», contrairement aux autres réponses.
jetlej
1
Voici une version améliorée qui corrige un bug lors de la sortie et de la rentrée de la pointe qui le cachait toujours, et corrige également le scénario lorsque la pointe est attachée au corps jsfiddle.net/Zf3m7/1499
Zoltán Tamási
14

Je pense qu'une manière simple serait la suivante:

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

De cette façon, le popover est créé à l'intérieur de l'élément cible lui-même. Ainsi, lorsque vous déplacez votre souris sur le popover, elle se trouve toujours sur l'élément. Bootstrap 3.3.2 fonctionne bien avec cela. Une version plus ancienne peut avoir des problèmes avec l'animation, vous pouvez donc désactiver "animation: false"

Cu Lý
la source
Je sais que ce fil est vieux, mais c'est la meilleure solution, la plus propre à mon avis et devrait être mieux classée. La seule mise en garde est que cela casserait, si vous positionnez le popover (d'une manière étrange) "loin" de l'élément déclencheur. Mais tant que la distance entre les deux est nulle (par exemple, ils se chevauchent), cela fonctionne à merveille et ne nécessite aucun JS personnalisé. Je vous remercie!
JohnGalt
C'est la solution la meilleure, la plus propre et la plus simple à ce jour. Devrait être classé plus haut! J'ai ajouté delay: { "hide": 400 }pour ajouter un délai avant de se cacher et cela fonctionne très bien! 👍
coorasse
14

J'ai utilisé le déclencheur défini sur hoveret donné le conteneur défini sur le, #elementpuis j'ai finalement ajouté un emplacement boxpour le right.

Cela devrait être votre configuration:

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

et #examplecss doit position:relative;vérifier le jsfiddle ci-dessous:

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

Édité

Ce violon a les deux liens qui fonctionnent sans problème http://jsfiddle.net/davidchase03/FQE57/4/

David Chase
la source
hmm qui fonctionne, puis-je utiliser jquery ajax en contentoption, pour prendre le contenu du côté du serveur ... cela fonctionnera ou je dois faire un travail supplémentaire pour cela
vikas devde
@vikasdevde oui, vous pouvez utiliser ajaxdans le contenu, mais vous devez configurer pour que cela fonctionne ... veuillez cocher la bonne réponse si cela a résolu votre OP.. afin que d'autres puissent en profiter
David Chase
mais si nous utilisons le lien lui-même comme conteneur, alors le popover entier devient un lien .... essayez-le
vikas devde
si vous mettez un lien à l'intérieur de la boîte, il sera toujours lié .. correct?
David Chase
2
Aucun des travaux de jsfiddle pour moi. Chrome 20 mars 2014.
pferrel
7

C'est ainsi que j'ai fait avec le popover bootstrap avec l'aide d'autres bits sur le net. Obtient dynamiquement le titre et le contenu de divers produits affichés sur le site. Chaque produit ou popover obtient un identifiant unique. Popover disparaîtra à la sortie du produit ($ this .pop) ou du popover. Timeout est utilisé où affichera le popover jusqu'à la sortie via le produit au lieu du 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();
    };
hoektoe
la source
Cela fonctionnera également si le popover n'est pas un enfant de l'élément cible. +1
Taha Paksu
6

Voici une solution que j'ai imaginée qui semble bien fonctionner tout en vous permettant d'utiliser l'implémentation normale de Bootstrap pour activer tous les popovers.

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

Porté sur 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');
});
eXpressiveDesign
la source
2

Je conviens 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 container: $(this)propriété comme suit:

$(selectorString).each(
  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 un .btnélément (bootstrap), vous ne pourrez pas sélectionner de texte dans le popover . Je voulais juste enregistrer ça puisque j'ai passé pas mal de temps à me cogner la tête là-dessus.

forumulator
la source
1

La réponse de Vikas fonctionne parfaitement pour moi, ici j'ajoute également le support du délai (afficher / masquer).

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

Veuillez également faire attention, j'ai changé:

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

avec:

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

de sorte qu'il référence exactement à ce popover ouvert, et pas à un autre (puisque maintenant, à travers le délai, plus de 1 pourrait être ouvert en même temps)

user1993198
la source
Le commentaire que j'ai fait à la fin n'est en fait pas correct lors de l'utilisation de container: body, si c'est le cas, je dois toujours utiliser la solution de Vikas pour cette ligne
user1993198
1

La réponse choisie fonctionne mais échouera si le popover est initialisé avec le bodycomme 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.$tipau lieu de traverser le DOM en espérant que le popover soit toujours un frère de l'élément.

Rubens Mariuzzo
la source
0

Même chose pour les info-bulles:

Pour moi, la solution suivante fonctionne car elle n'ajoute pas d'écouteurs d'événements à chaque 'mouseenter' et il est possible de revenir sur l'élément d'info-bulle qui maintient l'info-bulle en vie.

$ ->

  $('.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
phlppn
la source
0

Cette solution a bien fonctionné pour moi: (maintenant son pare-balles) ;-)

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);
    });
}
Johannes Ferner
la source
0
        $(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);
            });
        }); 
Dinesh Sarak
la source
0

J'ai trouvé que le mouseleavene se déclenche pas lorsque des choses étranges se produisent, comme le focus de la fenêtre change soudainement, puis l'utilisateur revient au navigateur. Dans des cas comme ça,mouseleave ne se déclenchera jamais tant que le curseur ne passera pas et ne quittera pas l'élément.

Cette solution que j'ai proposée repose sur mouseenterl' windowobjet, elle disparaît donc lorsque la souris est déplacée ailleurs sur la page.

Cela a été conçu pour fonctionner avec plusieurs éléments sur la page qui la déclencheront (comme dans un tableau).

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");
        }
    });
});
Gabriel Luci
la source
0

Il sera plus flexible avec 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);
    } 
)
Gray Li
la source
0

Facile :)

$('[data-toggle="popover"]').popover( { "container":"body", "trigger":"focus", "html":true });
$('[data-toggle="popover"]').mouseenter(function(){
    $(this).trigger('focus');
});
edmc73
la source
0

J'ai récemment eu besoin de faire fonctionner cela avec KO et les solutions ci-dessus ne fonctionnaient pas bien en cas de retard d'affichage et de masquage. Ce qui suit devrait résoudre ce problème. Basé sur le fonctionnement des info-bulles de bootstrap. J'espère que cela aide quelqu'un.

var options = {
                delay: { show: 1000, hide: 50 },
                trigger: 'manual',                      
                html: true
            };
var $popover = $(element).popover(options);

$popover.on('mouseenter', function () { // This is entering the triggering element
    var self = this;

    clearTimeout(self.timeout);
    self.hoverState = 'in';

    self.timeout = setTimeout(function () {
        if (self.hoverState == 'in') {
            $(self).popover("show");

            $(".popover, .popover *").on('mouseover', function () { // This is moving over the popover
                clearTimeout(self.timeout);
            });                                                                 

            $(".popover").on('mouseleave', function () { // This is leaving the popover
                self.timeout = setTimeout(function () {
                    if (self.hoverState == 'out') {
                        $(self).popover('hide');
                    }
                }, options.delay.hide);
            });
        }
    }, options.delay.show);
}).on('mouseleave', function (event) { // This is leaving the triggering element
    var self = this;

    clearTimeout(self.timeout);
    self.hoverState = 'out';

    self.timeout = setTimeout(function () {                             
        if (self.hoverState == 'out') {
            $(self).popover('hide');
        }

    }, options.delay.hide);
});
Zarthost Boman
la source
-1

Ceci est mon code pour afficher les info-bulles de dynamique avec délai et chargé par ajax.

$(window).on('load', function () {
    generatePopovers();
    
    $.fn.dataTable.tables({ visible: true, api: true }).on('draw.dt', function () {
        generatePopovers();
    });
});

$(document).ajaxStop(function () {
    generatePopovers();
});

function generatePopovers() {
var popover = $('a[href*="../Something.aspx"]'); //locate the elements to popover

popover.each(function (index) {
    var poplink = $(this);
    if (poplink.attr("data-toggle") == null) {
        console.log("RENDER POPOVER: " + poplink.attr('href'));
        poplink.attr("data-toggle", "popover");
        poplink.attr("data-html", "true");
        poplink.attr("data-placement", "top");
        poplink.attr("data-content", "Loading...");
        poplink.popover({
            animation: false,
            html: true,
            trigger: 'manual',
            container: 'body',
            placement: 'top'
        }).on("mouseenter", function () {
            var thispoplink = poplink;
            setTimeout(function () {
                if (thispoplink.is(":hover")) {
                    thispoplink.popover("show");
                    loadDynamicData(thispoplink); //load data by ajax if you want
                    $('body .popover').on("mouseleave", function () {
                        thispoplink.popover('hide');
                    });
                }
            }, 1000);
        }).on("mouseleave", function () {
            var thispoplink = poplink;
            setTimeout(function () {
                if (!$("body").find(".popover:hover").length) {
                    thispoplink.popover("hide");
                }
            }, 100);
        });
    }
});

function loadDynamicData(popover) {
    var params = new Object();
    params.somedata = popover.attr("href").split("somedata=")[1]; //obtain a parameter to send
    params = JSON.stringify(params);
    //check if the content is not seted
    if (popover.attr("data-content") == "Loading...") {
        $.ajax({
            type: "POST",
            url: "../Default.aspx/ObtainData",
            data: params,
            contentType: "application/json; charset=utf-8",
            dataType: 'json',
            success: function (data) {
                console.log(JSON.parse(data.d));
                var dato = JSON.parse(data.d);
                if (dato != null) {
                    popover.attr("data-content",dato.something); // here you can set the data returned
                    if (popover.is(":hover")) {
                        popover.popover("show"); //use this for reload the view
                    }
                }
            },

            failure: function (data) {
                itShowError("- Error AJAX.<br>");
            }
        });
    }
}

Giuliano
la source