Как привязать всплывающие подсказки Twitter Bootstrap к динамически создаваемым элементам?

277

Я использую всплывающие подсказки Twitter с javascript следующим образом:

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

Моя разметка выглядит так:

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

Это работает нормально, но я добавляю <a>элементы динамически, и всплывающие подсказки не отображаются для этих динамических элементов. Я знаю, это потому, что я связываю .tooltip () только один раз, когда документ загружен с типичной $(document).ready(function()функциональностью jquery .

Как я могу связать это с динамически созданными элементами? Обычно я делаю это с помощью метода jquery live (). Однако какое событие я использую для привязки? Я просто не уверен, как подключить загрузчик .tooltip () с помощью jquery .live ().

Я нашел один способ сделать эту работу что-то вроде этого:

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

Это работает, но кажется довольно хакерским. Я также вызываю точно такую ​​же строку .tooltip () в вызове $ (ready). Итак, элементы, которые существуют, когда страница сначала загружается и соответствует этому селектору, заканчиваются всплывающей подсказкой дважды?

Я не вижу проблем с этим подходом. Я просто ищу лучшую практику или понимание поведения.

durden2.0
источник
хм хороший вопрос, это поможет? github.com/twitter/bootstrap/issues/2374
Тим
Это интересное чтение, но мне нужна только подсказка одного типа. Я просто хочу убедиться, что добавляются любые динамически добавленные элементы, которые соответствуют селектору всплывающей подсказки, а это не так.
durden2.0
3
Отличный вопрос Похоже на чрезмерный сайт со стороны твиттера.
Люк Мрачный
1
@ durden2.0 Как христиане ответили на ваши вопросы? Хотите принять как правильно?
Руслан Уралов
3
На самом деле не имеет отношения к вашему вопросу, но ... я считаю плохим стилем присвоить relатрибут. Это несемантическое и возникло более десяти лет назад как взломать. В настоящее время каждый браузер, поддерживающий несколько лет назад, поддерживает data-*атрибуты, и больше нет причин не использовать их.
T Nguyen

Ответы:

513

Попробуй это:

$('body').tooltip({
    selector: '[rel=tooltip]'
});
Кристиан Странг
источник
4
Отлично. Это правильный ответ, потому что это в основном замена live / on.
Махн
5
Что мне не нравится в этом решении, так это то, что у вас не может быть нескольких настроек всплывающих подсказок. Например, это не работает, если у вас есть всплывающие подсказки, а другие - снизу.
Барболо
7
@barbolo, просто используйте разные селекторы для разных конфигураций. Это правильное решение. Кстати, это работает и с Popover.
Энрико Карлессо
16
загрузчик 3 использует $ ('body'). tooltip ({селектор: '[data-toggle = tooltip]'});
MERT DOĞAN
148

Если у вас есть несколько конфигураций всплывающей подсказки, которые вы хотите инициализировать, это хорошо работает для меня.

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

Затем вы можете установить свойство для отдельных элементов, используя dataатрибуты.

rohitmishra
источник
3
Отличный совет. Мне пришлось изменить его на $ ("body"). Tooltip ({selector: '[data-toggle = "tooltip"]'});
Jafin
2
Так должно быть с Bootstrap 3. Отлично!
мрачное
здорово! для использования внутри таблицы добавьте контейнер: 'body', чтобы избежать дополнительной ширины.
shock_gone_wild
Это работает очень хорошо. Я перепробовал кучу вещей на динамическом столе, но до этого ничего не получалось.
AnBisw
Работает и с Bootstrap 4!
Евгений Кулабухов
17

Для меня только перехват мышиного события был немного ошибочным, и всплывающая подсказка не отображалась / не скрывалась должным образом. Я должен был написать это, и теперь он работает отлично:

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

$(document).on('mouseleave','[rel=tooltip]', function(){
    $(this).tooltip('hide');
});
Паола Чериоли
источник
3
Это было очень полезно, чтобы понять, почему .on ('hover') не будет работать правильно.
Адам
Это было все, что мне нужно было использовать для моей реализации использования handlebars.js. Если я не использовал handlebars.js, принятый ответ также работал.
HPWD
Это то, как я делал это раньше, но вы теряете много опций, таких как задержки при наведении, которые вам, я думаю, нужно будет реализовать вручную.
DavidScherer
16

Я разместил более длинный ответ здесь: https://stackoverflow.com/a/20877657/207661

TL; DR: вам нужна только одна строка кода, которая выполняется в событии готовности документа:

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

Другой более сложный код, предложенный в других ответах, не кажется необходимым (я проверял это с помощью Bootstrap 3.0).

Шиталь шах
источник
1
Это лучший ответ.
Крис Марисик
Это сработало для моего случая. Я использовал таблицу с Tablesorter 2.26.2 и заполнял значения через вызов Ajax. Проблема заключалась в том, что всплывающая подсказка html отображалась как текст HTML, а не как выводимый результат. Это единственное решение, сработавшее для меня с первого взгляда. +1 и большое спасибо!
Anurag
8

Для меня это JS воспроизводит ту же проблему, которая происходит с Паолой

Мое решение:

$(document.body).tooltip({selector: '[title]'})
.on('click mouseenter mouseleave','[title]', function(ev) {
    $(this).tooltip('mouseenter' === ev.type? 'show': 'hide');
});
Д.г. жаккард
источник
2

Вместо того, чтобы искать его в полном теле. Я мог бы просто использовать динамический вариант заголовка, уже доступный в таких сценариях, я думаю:

$btn.tooltip({
  title: function(){
    return $(this).attr('title');
  }
});
Яскаран Сингх
источник
1

Я обнаружил, что комбинация этих ответов дала мне лучший результат - я все еще мог расположить подсказку и прикрепить ее к соответствующему контейнеру:

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

<button rel="tooltip" class="btn" data-placement="bottom" data-container=".some-parent" title="Show Tooltip">
    <i class="icon-some-icon"></i>
</button>
mattgi
источник