คำแนะนำเครื่องมือ 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.