Comment lier des info-bulles Twitter Bootstrap à des éléments créés dynamiquement?


277

J'utilise des info-bulles d'amorçage Twitter avec javascript comme suit:

$('a[rel=tooltip]').tooltip();

Mon balisage ressemble à ceci:

<a rel="tooltip" title="Not implemented" class="btn"><i class="icon-file"></i></a>

Cela fonctionne bien, mais j'ajoute des <a>éléments dynamiquement et les info-bulles ne s'affichent pas pour ces éléments dynamiques. Je sais que c'est parce que je ne lie .tooltip () qu'une seule fois lorsque le document est terminé chargé avec la $(document).ready(function()fonctionnalité jquery typique .

Comment puis-je le lier à des éléments créés dynamiquement? Habituellement, je le fais via la méthode jquery live (). Cependant, quel est l'événement que j'utilise pour lier? Je ne sais pas comment connecter le bootstrap .tooltip () avec jquery .live ().

J'ai trouvé une façon de faire fonctionner ça, c'est quelque chose comme ça:

/* Add new 'rows' when plus sign is clicked */
$("a.add").live('click', function () {
    var clicked_li = $(this).parent('li');
    var clone = clicked_li.clone();

    clone.find(':input').each(function() {
        $(this).val('');
    });

    clicked_li.after(clone);
    $('a[rel=tooltip]').tooltip();
});

Cela fonctionne, mais semble un peu hackish. J'appelle également exactement la même ligne .tooltip () dans l'appel $ (ready). Ainsi, les éléments qui existent lorsque la page se charge pour la première fois et correspondent à ce sélecteur se retrouvent-ils deux fois avec l'info-bulle?

Je ne vois aucun problème avec cette approche. Je cherche juste une meilleure pratique ou une compréhension du comportement.


hmm bonne question, ça va aider? github.com/twitter/bootstrap/issues/2374
Tim

C'est une lecture intéressante, mais je ne veux qu'un seul type d'infobulle. Je veux juste m'assurer que tous les éléments ajoutés dynamiquement qui correspondent au sélecteur d'infobulles sont ajoutés, ce qui n'est pas le cas.
durden2.0

3
Grande question. On dirait un oversite de la part de twitter.
Luke The Obscure

1
@ durden2.0 Comment les chrétiens ont-ils répondu à votre travail? Voulez-vous accepter comme correct?
Ruslans Uralovs

3
Pas vraiment lié à votre question mais ... Je trouve que c'est un mauvais style de détourner l' relattribut. Ce n'est pas sémantique et a été créé il y a plus de dix ans comme un hack. De nos jours, chaque navigateur datant de plusieurs années prend en charge les data-*attributs et il n'y a plus de raison de ne pas les utiliser.
T Nguyen

Réponses:


513

Essaye celui-là:

$('body').tooltip({
    selector: '[rel=tooltip]'
});

4
Génial. C'est la bonne réponse, car c'est essentiellement le substitut de live / on.
Mahn


5
Ce que je n'aime pas dans cette solution, c'est que vous ne pouvez pas avoir plusieurs configurations d'infobulles. Par exemple, cela ne fonctionne pas si vous avez des info-bulles placées en haut et d'autres en bas.
barbolo

7
@barbolo, utilisez simplement différents sélecteurs pour différentes configurations. C'est la bonne solution. Btw, cela fonctionne aussi avec Popover.
Enrico Carlesso

16
bootstrap 3 use $ ('body'). tooltip ({selector: '[data-toggle = tooltip]'});
MERT DOĞAN

148

Si vous souhaitez initialiser plusieurs configurations d'infobulles, cela fonctionne bien pour moi.

$("body").tooltip({
    selector: '[data-toggle="tooltip"]'
});

Vous pouvez ensuite définir la propriété sur des éléments individuels à l'aide d' dataattributs.


3
Bon conseil. J'ai dû le changer en $ ("body"). Tooltip ({selector: '[data-toggle = "tooltip"]'});
Jafin

2
C'est comme ça que ça devrait être avec Bootstrap 3. Génial!
sinistre

génial! pour une utilisation à l'intérieur d'une table, ajoutez un conteneur: 'body' pour éviter une largeur supplémentaire.
shock_gone_wild

Cela fonctionne vraiment bien. J'ai essayé tout un tas de trucs sur une table dynamique mais rien n'a vraiment fonctionné jusqu'à présent.
AnBisw

Fonctionne également avec Bootstrap 4!
Eugene Kulabuhov

17

Pour moi, attraper uniquement l'événement mouseenter était un peu bogué et l'info-bulle ne s'affichait pas / ne se cachait pas correctement. J'ai dû écrire ceci, et cela fonctionne maintenant parfaitement:

$(document).on('mouseenter','[rel=tooltip]', function(){
    $(this).tooltip('show');
});

$(document).on('mouseleave','[rel=tooltip]', function(){
    $(this).tooltip('hide');
});

3
C'était très utile pour savoir pourquoi .on ('hover') ne fonctionnerait pas correctement.
Adam

C'est tout ce dont j'avais besoin pour mon implémentation de l'utilisation de handlebars.js. Si je n'utilisais pas handlebars.js, la réponse acceptée a également fonctionné.
HPWD

C'est comme ça que je faisais cela, mais vous perdez beaucoup d'options comme les retards de survol que vous auriez besoin d'implémenter manuellement avec cela, je pense.
DavidScherer

16

J'ai posté une réponse plus longue ici: https://stackoverflow.com/a/20877657/207661

TL; DR: Vous n'avez besoin que d'une seule ligne de code qui s'exécute dans un événement prêt pour le document:

$(document.body).tooltip({ selector: "[title]" });

D'autres codes plus compliqués suggérés dans d'autres réponses ne semblent pas nécessaires (j'ai testé cela avec Bootstrap 3.0).


1
C'est la meilleure réponse.
Chris Marisic

Cela a fonctionné pour mon cas. J'ai utilisé une table avec Tablesorter 2.26.2 et rempli des valeurs via l'appel Ajax. Le problème était que l'infobulle html était affichée sous forme de texte HTML au lieu d'une sortie rendue. C'est la seule solution qui a fonctionné pour moi au premier coup. +1 et beaucoup de remerciements!
Anurag

8

Pour moi, ce js reproduit le même problème qui se produit avec Paola

Ma solution:

$(document.body).tooltip({selector: '[title]'})
.on('click mouseenter mouseleave','[title]', function(ev) {
    $(this).tooltip('mouseenter' === ev.type? 'show': 'hide');
});

2

Plutôt que de le rechercher dans tout le corps. On pourrait simplement utiliser l'option de titre dynamique déjà disponible dans de tels scénarios, je pense:

$btn.tooltip({
  title: function(){
    return $(this).attr('title');
  }
});

1

J'ai trouvé qu'une combinaison de ces réponses m'a donné le meilleur résultat - me permettant de toujours positionner l'infobulle et de la fixer au conteneur correspondant:

$('body').on('mouseenter', '[rel=tooltip]', function(){
  var el = $(this);
  if (el.data('tooltip') === undefined) {
    el.tooltip({
      placement: el.data("placement") || "top",
      container: el.data("container") || false
    });
  }
  el.tooltip('show');
});

$('body').on('mouseleave', '[rel=tooltip]', function(){
  $(this).tooltip('hide');
});

HTML pertinent:

<button rel="tooltip" class="btn" data-placement="bottom" data-container=".some-parent" title="Show Tooltip">
    <i class="icon-some-icon"></i>
</button>
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.