Etykietka interfejsu użytkownika Jquery nie obsługuje zawartości HTML

86

Dzisiaj zaktualizowałem wszystkie moje wtyczki jQuery za pomocą jQuery 1.9.1. Zacząłem używać podpowiedzi jQueryUI z jquery.ui.1.10.2. Wszystko było dobrze. Ale kiedy użyłem tagów HTML w treści (w titleatrybucie elementu, do którego stosowałem etykietkę), zauważyłem, że HTML nie jest obsługiwany.

To jest zrzut ekranu mojej podpowiedzi:

wprowadź opis obrazu tutaj

Jak sprawić, by zawartość HTML działała z etykietą narzędzia jQueryUI w wersji 1.10.2?

Andrew Whitaker
źródło
1
Czy to coś, co się zepsuło od czasu aktualizacji? Wydaje mi się, że działa dobrze w jQuery 1.9.1, jQuery UI 1.9.2 jsfiddle.net/2n3DL/1
metadept
Hmm, to dobry pomysł. Czy mogę zadać jeszcze jedno pytanie, jeśli mi pozwolisz. OK, mam ikonę podpowiedzi i ma ona klasę o nazwie "podpowiedź" w ten sposób: <img src = "images / info.png" class = "tooltip" title = "Trochę <b> świetny </b> HTML tekst podpowiedzi! "> Jak mogę tego używać? Z poważaniem.
zobacz zaktualizowane skrzypce metadeptów z jquery ui 1.10.2 tutaj i jquery 1.9.1. To nadal działa.
SachinGutte
@phobos: Nie, tak nie jest. W <b></b>podpowiedzi znajdują się tagi.
Andrew Whitaker
1
Najedź na „Niektóre dane wejściowe” (Etykietka narzędzia zwracająca bezpośrednio zawartość HTML działa dobrze). Wiem, że pytanie OP jest niejasne, ale zakładam, że używa on HTML w titleatrybucie, który nie jest obsługiwany od 1.10.
Andrew Whitaker

Odpowiedzi:

186

Edycja : Ponieważ ta odpowiedź okazała się popularna, dodaję zastrzeżenie, o którym @crush wspomniał w komentarzu poniżej. Jeśli używasz tego obejścia, pamiętaj, że otwierasz się na lukę w zabezpieczeniach XSS . Korzystaj z tego rozwiązania tylko wtedy, gdy wiesz, co robisz i możesz mieć pewność co do zawartości HTML w atrybucie.


Najłatwiejszym sposobem na to jest dostarczenie funkcji do contentopcji, która przesłania domyślne zachowanie:

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

Przykład: http://jsfiddle.net/Aa5nK/12/

Inną opcją byłoby zastąpienie widgetu podpowiedzi własnym, co zmienia contentopcję:

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

Teraz za każdym razem, gdy zadzwonisz .tooltip, zostanie zwrócona zawartość HTML.

Przykład: http://jsfiddle.net/Aa5nK/14/

Andrew Whitaker
źródło
4
Jedynym problemem jest to, że omija on sam powód, dla którego jQuery zaczął uciekać przed kodem HTML w atrybucie tytułu.
zmiażdżyć
4
@eidylon Putting HTML within the title attribute is not valid HTML and we are now escaping it to prevent XSS vulnerabilities. W odpowiedzi Andrzeja tytuł nadal musi zawierać kod HTML, który jest nieprawidłowy.
zmiażdżyć
Można mieć części tekstowej zawartości w atrybucie tytułowym, a następnie zbudować otaczających bitów HTML w treści zwrotnego aby obejść ten problem (tak długo, jak nie wiedział, co byłoby w Init czasie)
jinglesthula
18

Zamiast tego:

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

użyj tego dla lepszej wydajności

$(selector).tooltip({
    content: function () {
        return this.getAttribute("title");
    },
});
Profesor08
źródło
tak, lepsza wydajność, bo mam tylko kilka elementów z podpowiedziami
datdinhquoc
Działa idealnie
Helpha
14

Rozwiązałem to za pomocą niestandardowego znacznika danych, ponieważ i tak jest wymagany atrybut tytułu.

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

W ten sposób jest zgodny z HTML, a podpowiedzi są wyświetlane tylko dla poszukiwanych tagów.

Chris
źródło
5

Możesz to również osiągnąć całkowicie bez jQueryUI, używając stylów CSS. Zobacz fragment poniżej:

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>

Pierwszy zakres dotyczy wyświetlanego tekstu, a drugi zakresu tekstu ukrytego, który jest pokazywany po najechaniu na niego kursorem.

Matt
źródło
4

Aby rozwinąć powyższą odpowiedź @Andrew Whitaker, możesz przekonwertować podpowiedź na elementy HTML w tagu tytułu, aby uniknąć umieszczania surowego kodu HTML bezpośrednio w atrybutach:

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

Najczęściej podpowiedź jest przechowywana w zmiennej php, więc potrzebujesz tylko:

<div title="<?php echo htmlentities($tooltip); ?>">Hover Here</div>
billynoah
źródło
2

Aby uniknąć umieszczania tagów HTML w atrybucie tytułu, innym rozwiązaniem jest użycie przeceny. Na przykład możesz użyć [br] do oznaczenia końca wiersza, a następnie wykonać prostą zamianę w funkcji zawartości.

W atrybucie tytułu:

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

W funkcji treści :

content: function () {
    return $(this).attr('title').replace(/\[br\]/g,"<br />");
}
Flareman2020
źródło
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);
                 }
             }
         });
     });

dzięki za post i rozwiązanie powyżej.

Zaktualizowałem trochę kod. Mam nadzieję, że to może ci pomóc.

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

Pragnesh Karia
źródło
1

Tak długo, jak używamy jQuery (> v1.8), możemy przeanalizować przychodzący ciąg za pomocą $ .parseHTML ().

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

Przeanalizujemy atrybut ciągu przychodzącego pod kątem nieprzyjemnych rzeczy, a następnie przekonwertujemy go z powrotem na HTML czytelny dla jQuery. Piękno tego polega na tym, że zanim trafi do parsera, łańcuchy są już konkatenowane, więc nie ma znaczenia, czy ktoś próbuje podzielić tag skryptu na oddzielne ciągi. Jeśli utkniesz przy użyciu podpowiedzi jQuery, wydaje się to być solidnym rozwiązaniem.

ghettosoak
źródło
1

Możesz zmodyfikować kod źródłowy „jquery-ui.js”, znajdź tę domyślną funkcję do pobierania zawartości atrybutu tytułu elementu docelowego.

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

zmień to na

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

tak więc za każdym razem, gdy chcesz wyświetlać wskazówki HTML, po prostu dodaj atrybut ignoreHtml = 'false' do docelowego elementu html; lubię to <td title="<b>display content</b><br/>other" ignoreHtml='false'>display content</td>

Żartowniś
źródło
1

innym rozwiązaniem będzie pobranie tekstu wewnątrz titletagu, a następnie użycie .html()metody jQuery do skonstruowania zawartości podpowiedzi.

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

Przykład: http://jsfiddle.net/hamzeen/0qwxfgjo/

Hamzeen Hameem
źródło
1

Żadne z powyższych rozwiązań nie zadziałało. Ten działa dla mnie:

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

Znaczniki HTML

Element sterujący etykietą narzędzia z klasą „.why” i Obszar zawartości wskazówki narzędzia z klasą „.customTolltip”

$(function () {
                $('.why').attr('title', function () {
                    return $(this).next('.customTolltip').remove().html();
                });
                $(document).tooltip();
            });
Super Model
źródło
0

Zastąpienie \nlub uciekającego <br/>załatwia sprawę, zachowując resztę kodu HTML przed ucieczką:

$(document).tooltip({
    content: function() {
        var title = $(this).attr("title") || "";
        return $("<a>").text(title).html().replace(/&lt;br *\/?&gt;/, "<br/>");
    },
});
totalnothesenat
źródło
-1

dodaj html = true do opcji podpowiedzi

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

Aktualizacja
nie ma znaczenia dla właściwości podpowiedzi interfejsu użytkownika jQuery - to prawda w podpowiedziach interfejsu bootstrap - moja wina!

user2258511
źródło
1
Przepraszam, to nie zadziałało dla mnie. W oficjalnej dokumentacji nie ma również wzmianki o opcji „html”.
Wireblue
1
To jest dla podpowiedzi bootstrap 2.3, a nie podpowiedzi jquery-ui
Maciej Pyszyński
nie ma podpowiedzi „html” dla podpowiedzi
AmirHossein,