คำแนะนำเครื่องมือ Jquery UI ไม่รองรับเนื้อหา 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 = "HTML ที่ <b> ดี </b> บางอย่าง tooltip text! "> ฉันจะใช้แบบนี้ได้อย่างไร? ขอแสดงความนับถืออย่างสูง.

ดู metadepts ปรับปรุง fiddle ด้วย jquery ui 1.10.2 ที่นี่และ jquery 1.9.1 มันยังใช้งานได้
SachinGutte

@phobos: ไม่มันไม่ได้ มี<b></b>แท็กอยู่ในคำแนะนำเครื่องมือ
Andrew Whitaker

1
วางเมาส์เหนือ "อินพุตบางรายการ" (คำแนะนำเครื่องมือส่งคืนเนื้อหา HTML โดยตรงทำงานได้ดี) ฉันรู้ว่าคำถามของ OP นั้นไม่ชัดเจน แต่ฉันสมมติว่าเขาหรือเธอใช้ HTML ในtitleแอตทริบิวต์ซึ่งไม่ได้รับการสนับสนุนตั้งแต่ 1.10
Andrew Whitaker

คำตอบ:


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 เพื่อเริ่มต้นด้วย
ขยี้

4
@eidylon Putting HTML within the title attribute is not valid HTML and we are now escaping it to prevent XSS vulnerabilities. ในคำตอบของ Andrew ชื่อเรื่องยังคงต้องมี HTML ซึ่งไม่ถูกต้อง
ขยี้

คุณสามารถมีส่วนข้อความของเนื้อหาในแอตทริบิวต์ title จากนั้นสร้างบิต HTML โดยรอบในการเรียกกลับเนื้อหาของคุณเพื่อหลีกเลี่ยงสิ่งนี้ (ตราบเท่าที่คุณรู้ว่าจะเป็นอย่างไรในเวลาเริ่มต้น)
jinglesthula

18

แทนสิ่งนี้:

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

ใช้สิ่งนี้เพื่อประสิทธิภาพที่ดีขึ้น

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

ใช่ประสิทธิภาพที่ดีกว่าเพราะฉันมีเพียงไม่กี่องค์ประกอบที่มีคำแนะนำเครื่องมือ
datdinhquoc

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>

ช่วงแรกมีไว้สำหรับข้อความที่แสดงช่วงที่สองสำหรับข้อความที่ซ่อนอยู่ซึ่งจะแสดงเมื่อคุณวางเมาส์เหนือข้อความนั้น


3

หากต้องการขยายคำตอบของ @Andrew Whitaker ข้างต้นคุณสามารถแปลงคำแนะนำเครื่องมือของคุณเป็นเอนทิตี html ภายในแท็กหัวเรื่องเพื่อหลีกเลี่ยงการใส่ 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 อีกวิธีหนึ่งคือการใช้ markdown ตัวอย่างเช่นคุณสามารถใช้ [br] เพื่อแสดงการแบ่งบรรทัดจากนั้นทำการแทนที่อย่างง่ายในฟังก์ชันเนื้อหา

ในแอตทริบิวต์หัวเรื่อง:

"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 ภายในแอตทริบิวต์ title ไม่ใช่ HTML ที่ถูกต้องและตอนนี้เรากำลังหลบหนีเพื่อป้องกันช่องโหว่ XSS (ดู # 8861 )

หากคุณต้องการ HTML ในคำแนะนำเครื่องมือของคุณให้ใช้ตัวเลือกเนื้อหา - http://api.jqueryui.com/tooltip/#option-content 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 เพียงแค่เพิ่มแอตทริบิวต์เพิกเฉย Html = '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

การแทนที่\nหรือ Escape <br/>จะเป็นเคล็ดลับในขณะที่ทำให้ส่วนที่เหลือของ HTML Escape

$(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 - เป็นจริงในคำแนะนำเครื่องมือ bootstrap ui - ฉันไม่ดี!


1
ขออภัยสิ่งนี้ใช้ไม่ได้กับฉัน นอกจากนี้ยังไม่มีการกล่าวถึงตัวเลือก "html" ในเอกสารอย่างเป็นทางการ
Wireblue

1
นี่คือคำแนะนำเครื่องมือ bootstrap 2.3 ไม่ใช่คำแนะนำเครื่องมือ jquery-ui
Maciej Pyszyński

ไม่มี prop "html" สำหรับคำแนะนำเครื่องมือ
AmirHossein
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.