Всплывающая подсказка пользовательского интерфейса jquery не поддерживает HTML-контент


86

Сегодня я обновил все свои подключаемые модули jQuery с помощью jQuery 1.9.1. И я начал использовать всплывающую подсказку jQueryUI с jquery.ui.1.10.2. Все было хорошо. Но когда я использовал HTML-теги в содержимом (в titleатрибуте элемента, к которому я применял всплывающую подсказку), я заметил, что HTML не поддерживается.

Это скриншот моей всплывающей подсказки:

введите описание изображения здесь

Как я могу заставить HTML-контент работать с всплывающей подсказкой jQueryUI в 1.10.2?


1
Это что-то сломалось после того, как вы обновились? Кажется, у меня отлично работает jQuery 1.9.1, jQuery UI 1.9.2 jsfiddle.net/2n3DL/1
metadept

Хммм, это хорошая идея. Могу я задать еще один вопрос, если позволите. Хорошо, у меня есть значок всплывающей подсказки, и у него есть класс с именем "tooltip", например: <img src = "images / info.png" class = "tooltip" title = "Какой-то <b> отличный </b> HTML текст всплывающей подсказки! "> Как я могу это использовать? С уважением.

см. обновленную скрипку metadepts с jquery ui 1.10.2 здесь и jquery 1.9.1. Это все еще работает.
SachinGutte

@phobos: Нет, это не так. <b></b>Прямо во всплывающей подсказке есть теги.
Эндрю Уитакер

1
Наведите указатель мыши на «Некоторые данные» (всплывающая подсказка, непосредственно возвращающая HTML-контент, работает нормально). Я знаю, что вопрос OP непонятен, но я предполагаю, что он или она использует HTML в titleатрибуте, который не поддерживается с 1.10.
Эндрю Уитакер

Ответы:


186

Изменить : поскольку это оказался популярный ответ, я добавляю отказ от ответственности, который @crush упомянул в комментарии ниже. Если вы используете этот обходной путь, имейте в виду, что вы открываете себя для уязвимости XSS . Используйте это решение, только если вы знаете, что делаете, и можете быть уверены в содержании HTML в атрибуте.


Самый простой способ сделать это - предоставить функцию contentопции, которая отменяет поведение по умолчанию:

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

Пример: http://jsfiddle.net/Aa5nK/12/

Другой вариант - переопределить виджет всплывающей подсказки своим собственным, который изменяет contentпараметр:

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

Теперь каждый раз, когда вы звоните .tooltip, будет возвращаться HTML-контент.

Пример: http://jsfiddle.net/Aa5nK/14/


4
Единственная проблема с этим заключается в том, что он обходит саму причину, по которой jQuery начал экранировать HTML в атрибуте title.
Crush

4
@eidylon Putting HTML within the title attribute is not valid HTML and we are now escaping it to prevent XSS vulnerabilities. В ответе Эндрю заголовок по-прежнему должен содержать недопустимый HTML.
Crush

Вы могли бы иметь текстовую часть содержимого в атрибуте title, а затем создать окружающие фрагменты HTML в
обратном вызове

18

Вместо этого:

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

используйте это для лучшей производительности

$(selector).tooltip({
    content: function () {
        return this.getAttribute("title");
    },
});

да, производительность лучше, потому что у меня есть только несколько элементов с всплывающими подсказками
datdinhquoc

Работает отлично
Helpha

14

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

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

Таким образом, он соответствует HTML, и всплывающие подсказки отображаются только для желаемых тегов.


5

Вы также можете добиться этого полностью без jQueryUI, используя стили CSS. См. Фрагмент ниже:

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>

Первый диапазон предназначен для отображаемого текста, второй диапазон - для скрытого текста, который отображается при наведении на него курсора.


4

Чтобы расширить ответ @Andrew Whitaker выше, вы можете преобразовать всплывающую подсказку в объекты html в теге title, чтобы не помещать необработанный html непосредственно в свои атрибуты:

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

Чаще всего всплывающая подсказка в любом случае сохраняется в переменной php, поэтому вам понадобится только:

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

2

Чтобы избежать размещения HTML-тегов в атрибуте title, другим решением является использование уценки. Например, вы можете использовать [br] для обозначения разрыва строки, а затем выполнить простую замену в функции содержимого.

В атрибуте title:

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

В вашей контентной функции :

content: function () {
    return $(this).attr('title').replace(/\[br\]/g,"<br />");
}

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

спасибо за сообщение и решение выше.

Я немного обновил код. Надеюсь, это поможет вам.

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


1

Пока мы используем jQuery (> v1.8), мы можем анализировать входящую строку с помощью $ .parseHTML ().

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

Мы проанализируем атрибут входящей строки на предмет неприятных вещей, а затем преобразуем его обратно в HTML, читаемый с помощью jQuery. Прелесть этого заключается в том, что к тому времени, когда он попадает в парсер, строки уже связаны, поэтому не имеет значения, пытается ли кто-то разбить тег скрипта на отдельные строки. Если вы застряли в использовании всплывающих подсказок jQuery, это будет надежным решением.


1

С http://bugs.jqueryui.com/ticket/9019

Помещение HTML в атрибут заголовка не является допустимым HTML, и теперь мы избегаем его, чтобы предотвратить уязвимости XSS (см. №8861 ).

Если вам нужен HTML во всплывающих подсказках, используйте параметр содержимого - http://api.jqueryui.com/tooltip/#option-content .

Попробуйте использовать javascript для установки всплывающих подсказок html, см. Ниже

$( ".selector" ).tooltip({
   content: "Here is your HTML"
});

1

Вы можете изменить исходный код jquery-ui.js, найти эту функцию по умолчанию для получения содержимого атрибута title целевого элемента.

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

измените это на

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

таким образом, всякий раз, когда вы хотите отображать подсказки html, просто добавьте атрибут ignoreHtml = 'false' в свой целевой элемент html; как это <td title="<b>display content</b><br/>other" ignoreHtml='false'>display content</td>


1

другим решением будет захват текста внутри titleтега, а затем использование .html()метода jQuery для создания содержимого всплывающей подсказки.

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

Пример: http://jsfiddle.net/hamzeen/0qwxfgjo/


1

Ни одно из приведенных выше решений не помогло мне. Это работает для меня:

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

0

Разметка HTML

Элемент управления всплывающей подсказки с классом «.why» и область содержимого всплывающей подсказки с классом «.customTolltip»

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

0

Замена \nили экранированного <br/>делает трюк, при этом остальная часть HTML остается экранированной:

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

-1

добавить html = true в параметры всплывающей подсказки

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

Обновить,
это не актуально для свойства всплывающей подсказки jQuery ui - это правда в всплывающей подсказке пользовательского интерфейса начальной загрузки - моя проблема!


1
Извините, у меня это не сработало. Также в официальной документации нет упоминания об опции «html».
Wireblue

1
Это для всплывающей подсказки bootstrap 2.3, а не всплывающей подсказки jquery-ui
Maciej Pyszyński

для всплывающей подсказки нет свойства html
AmirHossein
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.