ความแตกต่างระหว่าง textContent กับ innerText


157

อะไรคือความแตกต่างระหว่างtextContentและinnerTextใน JavaScript?

ฉันสามารถใช้textContentดังต่อไปนี้:

var logo$ = document.getElementsByClassName('logo')[0];
logo$.textContent = "Example";

3
พวกมันเหมือนกัน แต่เบราว์เซอร์บางตัวรองรับอันอื่นและอีกอัน
Pointy

@Pointy เบราว์เซอร์ทั้งหมดที่รองรับคืออะไร
Yehia Awad

6
โพสต์บล็อกที่ดีเกี่ยวกับมัน
Tyblitz

4
@ คะแนนโปรดอ้างอิงจากโพสต์บล็อกที่ฉันชี้ไป ใบแจ้งยอดของคุณไม่ถูกต้องมีความแตกต่าง
Tyblitz

3
innerTextและtextContentจะไม่เหมือนเดิมอย่างแน่นอน พื้นที่ว่างสีขาวในเนื้อหาโหนดจะทำให้คุณสมบัติทั้งสองให้ผลลัพธ์เนื้อหาที่แตกต่างกันดังนั้นจะเกิดขึ้นของbrองค์ประกอบและลูกหลานที่สืบทอดการแสดงผลระดับบล็อกอื่น ๆ
พฤศจิกายน

คำตอบ:


211

ไม่มีคำตอบอื่นใดที่ประสบความสำเร็จในการให้คำอธิบายที่สมบูรณ์ ความแตกต่างที่สำคัญระหว่างinnerTextและtextContentมีการระบุไว้เป็นอย่างดีในบล็อกโพสต์เคลลี่นอร์ตัน: innerText กับ textContent ด้านล่างคุณจะพบข้อสรุป:

  1. innerTextไม่ได้มาตรฐานในขณะที่textContentได้มาตรฐานก่อนหน้านี้
  2. innerTextส่งคืนข้อความที่มองเห็นได้ในโหนดขณะที่textContentส่งคืนข้อความแบบเต็ม ตัวอย่างเช่นใน HTML ต่อไป<span>Hello <span style="display: none;">World</span></span>, innerTextจะกลับมา 'สวัสดี' ในขณะที่textContentจะกลับมา 'Hello World' สำหรับรายการความแตกต่างที่สมบูรณ์ยิ่งขึ้นโปรดดูตารางที่http://perfectionkills.com/the-poor-misunderstood-innerText/ (อ่านเพิ่มเติมที่'innerText' ทำงานใน IE แต่ไม่ใช่ใน Firefox )
  3. เป็นผลให้innerTextมีประสิทธิภาพมากขึ้นหนัก: มันต้องมีข้อมูลรูปแบบเพื่อส่งกลับผลลัพธ์
  4. innerTextถูกกำหนดไว้สำหรับHTMLElementวัตถุเท่านั้นในขณะที่textContentถูกกำหนดไว้สำหรับNodeวัตถุทั้งหมด

วิธีแก้ปัญหาสำหรับtextContentใน IE8- จะเกี่ยวข้องกับฟังก์ชันแบบเรียกซ้ำโดยใช้nodeValueบนchildNodesโหนดที่ระบุทั้งหมดนี่เป็นความพยายามของ polyfill:

function textContent(rootNode) {
  if ('textContent' in document.createTextNode(''))
    return rootNode.textContent;

  var childNodes = rootNode.childNodes,
      len = childNodes.length,
      result = '';

  for (var i = 0; i < len; i++) {
    if (childNodes[i].nodeType === 3)
      result += childNodes[i].nodeValue;
    else if (childNodes[i].nodeType === 1) 
      result += textContent(childNodes[i]);
  }

  return result;
}

16
ควรค่าแก่การสังเกตด้วย: innerTextจะเปลี่ยน<br>องค์ประกอบเป็นอักขระขึ้นบรรทัดใหม่ในขณะที่textContentจะเพิกเฉย ดังนั้น 2 คำที่มีเพียง<br>องค์ประกอบระหว่างพวกเขา (และไม่มีช่องว่าง) จะถูกต่อกันเมื่อใช้textContent
skerit

5
ถ้าเช่นนั้นมีความแตกต่างเมื่อใช้ setter หรือไม่? ชอบelem.textContent = 'foobar'VSelem.innerText = 'foobar'
แฟรงคลินยู

1
ความแตกต่างในการทำงานระหว่างอีกinnerTextและtextContent: ถ้าคุณเปลี่ยนtext-transformขององค์ประกอบโดย CSS ก็จะส่งผลกระทบต่อผลของ 'innerText' textContentแต่ไม่ได้ผลมาจากการ ตัวอย่างเช่น: innerTextจาก <div style="text-transform: uppercase;">Hello World</div>จะเป็น "HELLO WORLD" ในขณะที่textContentจะเป็น "Hello World"
Kobi

25

textContent เป็นหนึ่งเดียวที่พร้อมใช้งานสำหรับโหนดข้อความ:

var text = document.createTextNode('text');

console.log(text.innerText);    //  undefined
console.log(text.textContent);  //  text

ในโหนดองค์ประกอบให้innerTextประเมินองค์ประกอบของอีลิเมนต์ในขณะที่textContentประเมินอักขระควบคุม:

var span = document.querySelector('span');
span.innerHTML = "1<br>2<br>3<br>4\n5\n6\n7\n8";
console.log(span.innerText); // breaks in first half
console.log(span.textContent); // breaks in second half
<span></span>

span.innerText ให้:

1
2
3
4 5 6 7 8

span.textContent ให้:

1234
5
6
7
8

สตริงที่มีตัวควบคุม (เช่นฟีดบรรทัด) ไม่สามารถใช้ได้กับถ้าเนื้อหาที่ถูกกำหนดด้วยtextContent innerTextอีกวิธีหนึ่ง (ตั้งค่าอักขระควบคุมด้วยtextContent) อักขระทั้งหมดจะถูกส่งคืนทั้งด้วยinnerTextและtextContent:

var div = document.createElement('div');
div.innerText = "x\ny";
console.log(div.textContent);  //  xy


20

ทั้งสองinnerTextและtextContentมีมาตรฐานเป็นของปี 2016 ทั้งหมดNodeวัตถุ (รวมทั้งต่อมน้ำข้อความที่บริสุทธิ์) มีtextContentแต่เพียงวัตถุที่มีHTMLElementinnerText

แม้ว่าจะใช้textContentงานได้กับเบราว์เซอร์ส่วนใหญ่ แต่ก็ไม่สามารถทำงานได้บน IE8 หรือเก่ากว่า ใช้ polyfill นี้เพื่อใช้กับ IE8 เท่านั้น polyfill นี้จะไม่ทำงานกับ IE7 หรือก่อนหน้า

if (Object.defineProperty 
  && Object.getOwnPropertyDescriptor 
  && Object.getOwnPropertyDescriptor(Element.prototype, "textContent") 
  && !Object.getOwnPropertyDescriptor(Element.prototype, "textContent").get) {
  (function() {
    var innerText = Object.getOwnPropertyDescriptor(Element.prototype, "innerText");
    Object.defineProperty(Element.prototype, "textContent",
     {
       get: function() {
         return innerText.get.call(this);
       },
       set: function(s) {
         return innerText.set.call(this, s);
       }
     }
   );
  })();
}

Object.definePropertyเป็นวิธีการที่ไม่มีที่ใน IE9 หรือเพิ่มขึ้น แต่มันมีอยู่ใน IE8 สำหรับ DOM วัตถุเท่านั้น

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty

https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent


2
นี่คือข้อมูลจำเพาะของมันเช่นกัน: w3.org/TR/DOM-Level-3-Core/core.html นอกจากนี้ยังมีตารางสนับสนุนเบราว์เซอร์ (เก่ามาก) ( webdevout.net/browser-support-dom#dom3core ) ที่แนะนำด้วย มันรองรับ IE9 + ดังนั้นสำหรับ IE8 และรุ่นเก่ากว่านั้นinnerTextคือเพื่อนของคุณ
geekonaut

ที่จริงแล้วมันเป็นความคิดที่ดีกว่าที่จะไม่รองรับ ie8 หรือใช้ polyfill ฉันโพสต์โพลีฟิลในโพสต์ของฉัน
Richard Hamilton

1
วิธีการสามารถที่ทำงาน polyfill ใน IE8 เมื่อมันไม่สนับสนุนObject.defineProperty()?
Pointy

2
ทำไมคุณไม่อัปเดตคำตอบของคุณ? html.spec.whatwg.org/multipage/…
caub

3
นี่คือคำพูดจาก MDN เกี่ยวกับ InnerText - "ฟีเจอร์นี้เปิดตัวครั้งแรกโดย Internet Explorer และได้รับการระบุอย่างเป็นทางการในมาตรฐาน HTML ในปี 2016 หลังจากนำไปใช้โดยผู้ขายเบราว์เซอร์รายใหญ่
ชาด

15

สำหรับผู้ที่ googled คำถามนี้และมาถึงที่นี่ ผมรู้สึกว่าคำตอบที่ชัดเจนที่สุดสำหรับคำถามนี้อยู่ในเอกสาร MDN: https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent

คุณสามารถลืมคะแนนทั้งหมดที่อาจทำให้คุณสับสน แต่จำไว้ 2 สิ่ง:

  1. เมื่อคุณพยายามที่จะแก้ไขข้อความtextContentมักจะเป็นคุณสมบัติที่คุณกำลังมองหา
  2. เมื่อคุณพยายามที่จะคว้าข้อความจากองค์ประกอบบางอย่างinnerTextประมาณข้อความที่ผู้ใช้จะได้รับหากพวกเขาเน้นเนื้อหาขององค์ประกอบด้วยเคอร์เซอร์แล้วคัดลอกไปยังคลิปบอร์ด และtextContentมอบทุกอย่างให้คุณมองเห็นหรือซ่อนรวมทั้ง<script>และ<style>องค์ประกอบ

11

textContent รองรับเบราว์เซอร์ส่วนใหญ่ ไม่รองรับ ie8 หรือเก่ากว่า แต่สามารถใช้ polyfill ได้

คุณสมบัติ textContent ตั้งค่าหรือส่งคืนเนื้อหาข้อความของโหนดที่ระบุและการสืบทอดทั้งหมด

ดูhttp://www.w3schools.com/jsref/prop_node_textcontent.asp


0

textContent ส่งคืนข้อความเต็มและไม่สนใจการมองเห็นในขณะที่ innerText ทำ

<p id="source">
    <style>#source { color: red; }</style>
    Text with breaking<br>point.
    <span style="display:none">HIDDEN TEXT</span>
</p>

ผลลัพธ์ของ textContent:

#source { color: red; } Text with breakingpoint. HIDDEN TEXT

เอาต์พุตของ InnerText (โปรดทราบว่า InnerText ทราบแท็กอย่างไร<br>และไม่สนใจองค์ประกอบที่ซ่อนอยู่):

Text with breaking point.

ใน IE11 พฤติกรรมของ innerText จะเหมือนกับ textContent ตัวใดตัวหนึ่ง
เซบาสเตียน

0

นอกเหนือจากความแตกต่างทั้งหมดที่มีชื่อในคำตอบอื่น ๆ ที่นี่เป็นอีกหนึ่งที่ฉันค้นพบเมื่อเร็ว ๆ นี้:

แม้ว่าinnerTextคุณสมบัติได้รับการกล่าวถึงว่าเป็นมาตรฐานตั้งแต่ปี 2559 แต่ก็แสดงความแตกต่างระหว่างเบราว์เซอร์: Mozilla ละเว้นอักขระ U + 200E และ U + 200F ("lrm" และ "rlm") ในinnerTextขณะที่ Chrome ไม่

console.log(document.getElementById('test').textContent.length);
console.log(document.getElementById('test').innerText.length);
<div id="test">[&#x200E;]</div>

Firefox รายงาน 3 และ 2, Chrome รายงาน 3 และ 3

ยังไม่แน่ใจว่านี่เป็นข้อผิดพลาด (และถ้าเป็นเช่นนั้นเบราว์เซอร์ใด) หรือเพียงหนึ่งในสิ่งที่เข้ากันไม่ได้ที่เราต้องใช้ชีวิตด้วย


-1

innerHTML จะทำงานแม้กระทั่งแท็ก HTML ซึ่งอาจเป็นอันตรายทำให้เกิดการโจมตีด้านการฉีดใด ๆ เช่น DOMSS XSS นี่คือข้อมูลโค้ด:

<!DOCTYPE html>
<html>
    <body>
        <script>
            var source = "Hello " + decodeURIComponent("<h1>Text inside gets executed as h1 tag HTML is evaluated</h1>");  //Source
            var divElement = document.createElement("div");
            divElement.innerHTML = source;  //Sink
            document.body.appendChild(divElement);
        </script>
    </body>
</html>

หากคุณใช้. textContent จะไม่ประเมินแท็ก HTML และพิมพ์เป็นสตริง

<!DOCTYPE html>
<html>
    <body>
        <script>
            var source = "Hello " + decodeURIComponent("<h1>Text inside will not get executed as HTML</h1>");  //Source
            var divElement = document.createElement("div");
            divElement.textContent = source;  //Sink
            document.body.appendChild(divElement);
        </script>
    </body>
</html>

การอ้างอิง: https://www.scip.ch/en/?labs.20171214

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