Como vincular as dicas de ferramentas do Twitter Bootstrap a elementos criados dinamicamente?

277

Estou usando as dicas de ferramentas de auto-inicialização do Twitter com javascript, da seguinte maneira:

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

Minha marcação é assim:

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

Isso funciona bem, mas adiciono <a>elementos dinamicamente e as dicas de ferramentas não estão aparecendo para esses elementos dinâmicos. Eu sei que é porque eu só vinculo .tooltip () uma vez quando o documento é carregado com a $(document).ready(function()funcionalidade jquery típica .

Como vincular isso a elementos criados dinamicamente? Normalmente, eu faria isso através do método jquery live (). No entanto, qual é o evento que eu uso para ligar? Só não sei como conectar o bootstrap .tooltip () ao jquery .live ().

Eu encontrei uma maneira de fazer isso funcionar é algo como isto:

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

Isso funciona, mas parece meio tolo. Também estou chamando exatamente a mesma linha .tooltip () na chamada $ (ready). Então, os elementos que existem quando a página é carregada pela primeira vez e correspondem a esse seletor terminam com a dica de ferramenta duas vezes?

Não vejo problemas com essa abordagem. Estou apenas procurando uma melhor prática ou compreensão do comportamento.

durden2.0
fonte
hmm boa pergunta, isso vai ajudar? github.com/twitter/bootstrap/issues/2374
Tim
Essa é uma leitura interessante, mas eu só quero um único tipo de dica de ferramenta. Eu só quero garantir que quaisquer elementos adicionados dinamicamente que correspondam ao seletor de dicas de ferramentas sejam adicionados, o que não é o caso.
precisa saber é o seguinte
3
Ótima pergunta. Parece um oversite por parte do twitter.
Luke The Obscure
1
@ durden2.0 Como os cristãos responderam a você? Gostaria de aceitar como correto?
Ruslans Uralovs
3
Não está realmente relacionado à sua pergunta, mas ... Acho que é um estilo ruim seqüestrar o relatributo. Isso não é semântico e foi originado há mais de uma década como um hack. Atualmente, todos os navegadores que remontam a vários anos suportam data-*atributos e não há mais motivos para não usá-los.
T Nguyen

Respostas:

513

Tente este:

$('body').tooltip({
    selector: '[rel=tooltip]'
});
Christian Strang
fonte
4
Ótimo. Esta é a resposta correta, porque é basicamente o substituto do live / on.
Mahn
5
O que eu não gosto nessa solução é que você não pode ter várias configurações de dicas de ferramentas. Por exemplo, não funciona se você tiver dicas de ferramentas colocadas em cima e outras colocadas em baixo.
barbolo
7
@barbolo, basta usar diferentes seletores para diferentes configurações. Esta é a solução certa. Aliás, ele também funciona com Popover.
Enrico Carlesso 19/09/12
16
o bootstrap 3 usa $ ('body'). dica de ferramenta ({selector: '[data-toggle = tooltip]'});
MERT DOĞAN
148

Se você tiver várias configurações de dicas de ferramentas que deseja inicializar, isso funcionará bem para mim.

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

Você pode definir a propriedade em elementos individuais usando dataatributos.

rohitmishra
fonte
3
Ótima dica. Eu tive que mudar para $ ("body"). Tooltip ({selector: '[data-toggle = "tooltip"]'});
Jafin
2
É assim que deve ser com o Bootstrap 3. Ótimo!
sombrio
ótimo! para uso dentro de uma mesa, adicione o contêiner: 'body' para evitar largura extra.
shock_gone_wild
Isso funciona muito bem. Eu tentei um monte de coisas em uma tabela dinâmica, mas nada funcionou até isso.
AnBisw 17/04
Também funciona com o Bootstrap 4!
Eugene Kulabuhov 26/03
17

Para mim, apenas capturar o evento do mouseenter era um pouco complicado, e a dica de ferramenta não estava aparecendo / ocultando corretamente. Eu tive que escrever isso, e agora está funcionando perfeitamente:

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

$(document).on('mouseleave','[rel=tooltip]', function(){
    $(this).tooltip('hide');
});
Paola Cerioli
fonte
3
Isso foi muito útil, por que razão .on ('pairar') não funcionaria corretamente.
Adam
Era tudo o que eu precisava para minha implementação do handlebars.js. Se eu não estivesse usando o handlebars.js, a resposta aceita também funcionaria.
HPWD 20/09/18
É assim que eu costumava fazer isso, mas você perde muitas opções, como atrasos de foco, que precisaria implementar manualmente com isso, eu acho.
DavidScherer 8/02/19
16

Publiquei uma resposta mais longa aqui: https://stackoverflow.com/a/20877657/207661

TL; DR: você precisa de apenas uma linha de código que é executada no evento pronto para documento:

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

Outro código mais complicado sugerido em outras respostas não parece necessário (eu testei isso com o Bootstrap 3.0).

Shital Shah
fonte
1
Esta é a melhor resposta.
Chris Marisic
Isso funcionou para o meu caso. Usei uma tabela com o Tablesorter 2.26.2 e os valores preenchidos via chamada do Ajax. O problema era que a dica de ferramenta html era mostrada como texto HTML em vez de saída renderizada. Esta é a única solução que funcionou para mim desde o início. +1 e muito obrigado!
Anurag
8

Para mim, esse js reproduz o mesmo problema que acontece com Paola

Minha solução:

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

Em vez de procurá-lo em corpo inteiro. Pode-se usar a opção de título dinâmico já disponível em tais cenários, eu acho:

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

Descobri que uma combinação dessas respostas me deu o melhor resultado - permitindo que eu ainda posicione a dica e a anexe ao contêiner relevante:

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

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