ChatGPT解决这个技术问题 Extra ChatGPT

How do I bind Twitter Bootstrap tooltips to dynamically created elements?

I'm using Twitter bootstrap tooltips with javascript like the following:

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

My markup looks like this:

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

This works fine, but I add <a> elements dynamically and the tooltips aren't showing up for those dynamic elements. I know it's because I only bind .tooltip() once when the document is finished loaded with the typical jquery $(document).ready(function() functionality.

How can I bind this to dynamically created elements? Usually I would do this via the jquery live() method. However, what is the event that I use to bind? I'm just not sure how to hook up the bootstrap .tooltip() with jquery .live().

I've found one way to make this work is something like this:

/* 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();
});

This works, but seems kind of hackish. I'm also calling the exact same .tooltip() line in the $(ready) call. So, do the elements that exist when the page first loads and match that selector end up with the tooltip twice?

I don't see any problems with this approach. I'm just looking for a best practice or understanding of the behavior.

hmm good question, will this help? github.com/twitter/bootstrap/issues/2374
That's an interesting read, but I'm only wanting a single type of tooltip. I just want to make sure any dynamically added elements that match the tooltip selector get added, which isn't the case.
Great question. Seems like an oversite on the part of twitter.
@durden2.0 How did Christians answer work for you? Care to accept as correct?
Not really related to your question but... I find it bad style to hijack the rel attribute. This is non-semantic and was originated over a decade ago as a hack. Nowadays, every single browser going back several years supports data-* attributes and there's no more reason not to use them.

C
Christian Strang

Try this one:

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

Great. This is the correct answer, because it's basically the substitute of live/on.
What I don't like about this solution is that you can't have multiple configuration of tooltips. For example, it doesn't work if you have tooltips that are placed on top and others that are placed on bottom.
@barbolo, simply use different selectors for different configurations. This is the right solution. Btw, it works also with Popover.
bootstrap 3 use $('body').tooltip({selector:'[data-toggle=tooltip]'});
N
Nobody

If you have multiple tooltip configurations that you want to initialise, this works well for me.

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

You can then set the property on individual elements using data attributes.


Great tip. I had to change it to $("body").tooltip({ selector: '[data-toggle="tooltip"]' });
This is how it should be with Bootstrap 3. Great!
great! for use inside a table add container: 'body' to avoid extra width.
This works really well. I tried a whole bunch of stuff on a dynamic table but nothing really worked until this.
Works with Bootstrap 4 as well!
P
Paola Cerioli

For me, only catching the mouseenter event was a bit buggy, and the tooltip was not showing/hiding properly. I had to write this, and it is now working perfectly:

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

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

This was very helpful insite as to why .on('hover') wouldn't work right.
This was all I needed to use for my implementation of using handlebars.js. If I wasn't using handlebars.js, the accepted answer also worked.
This is how I used to do this but you lose a lot of options like hover delays that you would need to implement manually with this I think.
C
Community

I've posted longer answer here: https://stackoverflow.com/a/20877657/207661

TL;DR: You need only one line of code that runs in document ready event:

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

Other more complicated code suggested in other answers don't seem necessary (I've tested this with Bootstrap 3.0).


This is the best answer.
This worked for my case. I used a table with Tablesorter 2.26.2 and populated values via Ajax call. Problem was that the html tooltip was shown as HTML text instead of rendered output. This is the only solution worked for me in the first go. +1 and lot of thanks!
C
Community

For me, this js reproduces the same problem that happens with Paola

My solution:

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

J
Jaskaran Singh

Rather than search it in full Body. One could just use dynamic title option already available in such scenarios I think:

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

m
mattgi

I found a combination of these answers gave me the best outcome - allowing me to still position the tooltip and attach it to the relevant container:

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

Relevant HTML:

<button rel="tooltip" class="btn" data-placement="bottom" data-container=".some-parent" title="Show Tooltip">
    <i class="icon-some-icon"></i>
</button>

W
Webucator

In Bootstrap 5, which doesn't use jQuery, you can do this:

const btn = document.createElement('button'); btn.innerHTML = 'Click me'; btn.dataset['toggle'] = 'tooltip'; btn.dataset['placement'] = 'top'; btn.title = 'Your Tooltip Here'; new bootstrap.Tooltip(btn); document.getElementById('parent').appendChild(btn);