A dica de ferramenta da IU do Jquery não suporta conteúdo html

86

Hoje, eu atualizei todos os meus plug-ins jQuery com jQuery 1.9.1. E comecei a usar a dica de ferramenta jQueryUI com jquery.ui.1.10.2. Tudo estava bom. Mas quando usei tags HTML no conteúdo (no titleatributo do elemento ao qual estava aplicando a dica de ferramenta), percebi que não há suporte para HTML.

Esta é uma captura de tela da minha dica:

insira a descrição da imagem aqui

Como posso fazer o conteúdo HTML funcionar com a dica de ferramenta jQueryUI em 1.10.2?

Andrew Whitaker
fonte
1
Isso é algo que quebrou desde que você atualizou? Parece funcionar bem para mim no jQuery 1.9.1, jQuery UI 1.9.2 jsfiddle.net/2n3DL/1
metadept
Hımm. É uma boa ideia. Posso fazer mais uma pergunta, se você deixar. Ok, eu tenho um ícone de dica de ferramenta e uma classe chamada "dica de ferramenta" assim: <img src = "images / info.png" class = "tooltip" title = "Um HTML <b> ótimo </b> tooltip text! "> Como posso usar assim? Cumprimentos.
veja metadepts atualizados sobre o violino com jquery ui 1.10.2 aqui e jquery 1.9.1. Ainda funciona.
SachinGutte
@phobos: Não, não importa. Existem <b></b>tags na dica de ferramenta.
Andrew Whitaker
1
Passe o mouse sobre "Alguma entrada" (a dica de ferramenta que retorna diretamente o conteúdo HTML funciona bem). Eu sei que a pergunta do OP não está clara, mas estou supondo que ele ou ela está usando HTML no titleatributo, que não é compatível desde o 1.10.
Andrew Whitaker

Respostas:

186

Edit : Uma vez que esta se tornou uma resposta popular, estou adicionando o aviso de que @crush mencionou em um comentário abaixo. Se você usar essa solução alternativa, esteja ciente de que está se abrindo para uma vulnerabilidade de XSS . Use esta solução apenas se você souber o que está fazendo e tiver certeza do conteúdo HTML no atributo.


A maneira mais fácil de fazer isso é fornecer uma função para a contentopção que substitui o comportamento padrão:

$(function () {
      $(document).tooltip({
          content: function () {
              return $(this).prop('title');
          }
      });
  });

Exemplo: http://jsfiddle.net/Aa5nK/12/

Outra opção seria substituir o widget de dica de ferramenta pelo seu próprio que altera a contentopção:

$.widget("ui.tooltip", $.ui.tooltip, {
    options: {
        content: function () {
            return $(this).prop('title');
        }
    }
});

Agora, toda vez que você ligar .tooltip, o conteúdo HTML será retornado.

Exemplo: http://jsfiddle.net/Aa5nK/14/

Andrew Whitaker
fonte
4
O único problema com isso é contornar a própria razão pela qual jQuery começou a escapar HTML no atributo title para começar.
esmagamento em
4
@eidylon Putting HTML within the title attribute is not valid HTML and we are now escaping it to prevent XSS vulnerabilities. Na resposta de Andrew, o título ainda deve conter HTML, que é inválido.
esmagamento em
Você poderia ter a parte textual do conteúdo no atributo title e, em seguida, construir os bits circundantes de HTML em seu callback de conteúdo para contornar isso (contanto que você soubesse o que seria no momento do init)
jinglesthula
18

Em vez disso:

$(document).tooltip({
    content: function () {
        return $(this).prop('title');
    }
});

use isso para melhor desempenho

$(selector).tooltip({
    content: function () {
        return this.getAttribute("title");
    },
});
Profesor08
fonte
sim, melhor desempenho, porque eu só tenho alguns elementos com dicas
datdinhquoc
Funciona perfeitamente
Helpha,
14

Eu resolvi isso com uma tag de dados personalizada, porque um atributo de título é necessário de qualquer maneira.

$("[data-tooltip]").each(function(i, e) {
    var tag = $(e);
    if (tag.is("[title]") === false) {
        tag.attr("title", "");
    }
});

$(document).tooltip({
    items: "[data-tooltip]",
    content: function () {
        return $(this).attr("data-tooltip");
    }
});

Assim, ele está em conformidade com o html e as dicas de ferramentas são mostradas apenas para as tags desejadas.

Chris
fonte
5

Você também pode conseguir isso completamente sem jQueryUI usando estilos CSS. Veja o snippet abaixo:

div#Tooltip_Text_container {
  max-width: 25em;
  height: auto;
  display: inline;
  position: relative;
}

div#Tooltip_Text_container a {
  text-decoration: none;
  color: black;
  cursor: default;
  font-weight: normal;
}

div#Tooltip_Text_container a span.tooltips {
  visibility: hidden;
  opacity: 0;
  transition: visibility 0s linear 0.2s, opacity 0.2s linear;
  position: absolute;
  left: 10px;
  top: 18px;
  width: 30em;
  border: 1px solid #404040;
  padding: 0.2em 0.5em;
  cursor: default;
  line-height: 140%;
  font-size: 12px;
  font-family: 'Segoe UI';
  -moz-border-radius: 3px;
  -webkit-border-radius: 3px;
  border-radius: 3px;
  -moz-box-shadow: 7px 7px 5px -5px #666;
  -webkit-box-shadow: 7px 7px 5px -5px #666;
  box-shadow: 7px 7px 5px -5px #666;
  background: #E4E5F0  repeat-x;
}

div#Tooltip_Text_container:hover a span.tooltips {
  visibility: visible;
  opacity: 1;
  transition-delay: 0.2s;
}

div#Tooltip_Text_container img {
  left: -10px;
}

div#Tooltip_Text_container:hover a span.tooltips {
  visibility: visible;
  opacity: 1;
  transition-delay: 0.2s;
}
<div id="Tooltip_Text_container">
  <span><b>Tooltip headline</b></span>
  <a href="#">
    <span class="tooltips">
        <b>This is&nbsp;</b> a tooltip<br/>
        <b>This is&nbsp;</b> another tooltip<br/>
    </span>
  </a>
  <br/>Move the mousepointer to the tooltip headline above. 
</div>

O primeiro intervalo é para o texto exibido, o segundo intervalo para o texto oculto, que é mostrado quando você passa o mouse sobre ele.

Matt
fonte
4

Para expandir a resposta de @Andrew Whitaker acima, você pode converter sua dica de ferramenta em entidades html dentro da tag de título para evitar colocar HTML bruto diretamente em seus atributos:

$('div').tooltip({
    content: function () {
        return $(this).prop('title');
    }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script src="http://code.jquery.com/ui/1.9.2/jquery-ui.js"></script>
<div class="tooltip" title="&lt;div&gt;check out these kool &lt;i&gt;italics&lt;/i&gt; and this &lt;span style=&quot;color:red&quot;&gt;red text&lt;/span&gt;&lt;/div&gt;">Hover Here</div>

Na maioria das vezes, a dica de ferramenta é armazenada em uma variável php de qualquer maneira, então você só precisa:

<div title="<?php echo htmlentities($tooltip); ?>">Hover Here</div>
Billynoah
fonte
2

Para evitar colocar tags HTML no atributo title, outra solução é usar markdown. Por exemplo, você pode usar [br] para representar uma quebra de linha e, em seguida, realizar uma substituição simples na função de conteúdo.

No atributo title:

"Sample Line 1[br][br]Sample Line 2"

Em sua função de conteúdo :

content: function () {
    return $(this).attr('title').replace(/\[br\]/g,"<br />");
}
Flareman2020
fonte
1
$(function () {
         $.widget("ui.tooltip", $.ui.tooltip, {
             options: {
                 content: function () {
                     return $(this).prop('title');
                 }
             }
         });

         $('[rel=tooltip]').tooltip({
             position: {
                 my: "center bottom-20",
                 at: "center top",
                 using: function (position, feedback) {
                     $(this).css(position);
                     $("<div>")
                         .addClass("arrow")
                         .addClass(feedback.vertical)
                         .addClass(feedback.horizontal)
                         .appendTo(this);
                 }
             }
         });
     });

obrigado pela postagem e solução acima.

Eu atualizei um pouco o código. Espero que isso possa ajudá-lo.

http://jsfiddle.net/pragneshkaria/Qv6L2/49/

Pragnesh Karia
fonte
1

Enquanto estivermos usando jQuery (> v1.8), podemos analisar a string de entrada com $ .parseHTML ().

$('.tooltip').tooltip({
    content: function () {
        var tooltipContent = $('<div />').html( $.parseHTML( $(this).attr('title') ) );
        return tooltipContent;
    },
}); 

Vamos analisar o atributo da string de entrada em busca de coisas desagradáveis ​​e, em seguida, convertê-lo de volta em HTML legível por jQuery. A beleza disso é que, no momento em que atinge o analisador, as strings já estão concatenadas, então não importa se alguém está tentando dividir a tag do script em strings separadas. Se você está travado usando as dicas de ferramentas do jQuery, esta parece ser uma solução sólida.

gueto
fonte
1

Você pode modificar o código-fonte 'jquery-ui.js', encontrar esta função padrão para recuperar o conteúdo do atributo de título do elemento de destino.

var tooltip = $.widget( "ui.tooltip", {
version: "1.11.4",
options: {
    content: function() {
        // support: IE<9, Opera in jQuery <1.7
        // .text() can't accept undefined, so coerce to a string
        var title = $( this ).attr( "title" ) || "";
        // Escape title, since we're going from an attribute to raw HTML
        return $( "<a>" ).text( title ).html();
    },

mude para

var tooltip = $.widget( "ui.tooltip", {
version: "1.11.4",
options: {
    content: function() {
        // support: IE<9, Opera in jQuery <1.7
        // .text() can't accept undefined, so coerce to a string
        if($(this).attr('ignoreHtml')==='false'){
            return $(this).prop("title");
        }
        var title = $( this ).attr( "title" ) || "";
        // Escape title, since we're going from an attribute to raw HTML
        return $( "<a>" ).text( title ).html();
    },

portanto, sempre que você quiser exibir dicas de html, apenas adicione um atributo ignoreHtml = 'false' em seu elemento html de destino; como isso <td title="<b>display content</b><br/>other" ignoreHtml='false'>display content</td>

Palhaço
fonte
1

outra solução será pegar o texto dentro da titletag e usar o .html()método do jQuery para construir o conteúdo da dica de ferramenta.

$(function() {
  $(document).tooltip({
    position: {
      using: function(position, feedback) {
        $(this).css(position);
        var txt = $(this).text();
        $(this).html(txt);
        $("<div>")
          .addClass("arrow")
          .addClass(feedback.vertical)
          .addClass(feedback.horizontal)
          .appendTo(this);
      }
    }
  });
});

Exemplo: http://jsfiddle.net/hamzeen/0qwxfgjo/

Hamzeen Hameem
fonte
1

Nenhuma das soluções acima funcionou para mim. Este funciona para mim:

$(document).ready(function()
{
    $('body').tooltip({
        selector: '[data-toggle="tooltip"]',
        html: true
     });
});
Avión
fonte
0

Html Markup

Controle de dica de ferramenta com classe ".why" e Área de conteúdo de dica de ferramenta com classe ".customTolltip"

$(function () {
                $('.why').attr('title', function () {
                    return $(this).next('.customTolltip').remove().html();
                });
                $(document).tooltip();
            });
Super Model
fonte
0

Substituir o \nou o escapado <br/>resolve o problema, enquanto mantém o resto do HTML escapado:

$(document).tooltip({
    content: function() {
        var title = $(this).attr("title") || "";
        return $("<a>").text(title).html().replace(/&lt;br *\/?&gt;/, "<br/>");
    },
});
totalmente nada senão
fonte
-1

adicione html = true às opções de dica de ferramenta

$({selector}).tooltip({html: true});

A atualização
não é relevante para a propriedade de dica de ferramenta da interface do usuário do jQuery - é verdade na dica de ferramenta da interface do usuário de bootstrap - que pena!

user2258511
fonte
1
Desculpe, isso não funcionou para mim. Também não há menção de uma opção "html" na documentação oficial.
Wireblue
1
Isso é para bootstrap 2.3 tooltip, não jquery-ui tooltip
Maciej Pyszyński
não há prop "html" para a dica
AmirHossein