Unterschied zwischen textContent und innerText

156

Was ist der Unterschied zwischen textContentund innerTextin JavaScript?

Kann ich textContentwie folgt verwenden:

var logo$ = document.getElementsByClassName('logo')[0];
logo$.textContent = "Example";
JK
quelle
3
Sie sind gleich, aber einige Browser unterstützen den einen und andere den anderen.
Pointy
@Pointy Was unterstützen alle Browser?
Yehia Awad
6
Ein guter Blog-Beitrag darüber
Tyblitz
4
@Pointy beziehen Sie sich bitte auf den Blog-Beitrag, auf den ich hingewiesen habe. Ihre Aussage ist falsch, es gibt einen Unterschied.
Tyblitz
3
innerTextund textContentsind entschieden nicht gleich. Leerzeichen im Knoteninhalt führen dazu, dass die beiden Eigenschaften unterschiedliche Inhalte ergeben, ebenso wie das Auftreten von brElementen und anderen auf Blockebene gerenderten Nachkommen.
Amn

Antworten:

210

Keine der anderen Antworten liefert die vollständige Erklärung, daher diese. Die wichtigsten Unterschiede zwischen innerTextund textContentwerden in Kelly Nortons Blogpost sehr gut umrissen : innerText vs. textContent . Nachfolgend finden Sie eine Zusammenfassung:

  1. innerTextwar nicht Standard, während textContentfrüher standardisiert wurde.
  2. innerTextGibt den sichtbaren Text zurück, der in einem Knoten enthalten ist, während textContentder vollständige Text zurückgegeben wird. Zum Beispiel auf der folgenden HTML <span>Hello <span style="display: none;">World</span></span>, innerTextkehrt ‚Hallo‘, während textContentkehrt ‚Hallo Welt‘. Eine vollständigere Liste der Unterschiede finden Sie in der Tabelle unter http://perfectionkills.com/the-poor-misunderstood-innerText/ (weitere Informationen unter 'innerText' funktionieren im IE, jedoch nicht in Firefox ).
  3. Infolgedessen innerTextist es viel leistungsintensiver: Es erfordert Layoutinformationen, um das Ergebnis zurückzugeben.
  4. innerTextist nur für HTMLElementObjekte definiert , während textContentfür alle NodeObjekte definiert ist .

Eine textContentProblemumgehung für in IE8- würde eine rekursive Funktion beinhalten, die nodeValueauf allen childNodesangegebenen Knoten verwendet wird. Hier ist ein Versuch mit einer Polyfüllung:

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;
}
Tyblitz
quelle
16
Auch erwähnenswert: innerTextschaltet <br>Elemente in Zeilenumbrüche, während textContentwird einfach ignorieren. Also werden 2 Wörter mit nur einem <br>Element dazwischen (und ohne Leerzeichen) bei der Verwendung verkettettextContent
Skerit
5
Gibt es dann einen Unterschied, wenn der Setter verwendet wird? Wie elem.textContent = 'foobar'vselem.innerText = 'foobar'
Franklin Yu
1
Ein weiterer Unterschied im Verhalten zwischen innerTextund textContent: Wenn Sie das text-transformeines Elements durch CSS ändern, wirkt sich dies auf das Ergebnis von 'innerText' aus, nicht jedoch auf das Ergebnis von textContent. Zum Beispiel: innerTextvon <div style="text-transform: uppercase;">Hello World</div>wird "HALLO WORLD" sein, während textContent"Hello World" sein wird.
Kobi
25

textContent ist der einzige verfügbare Textknoten:

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

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

innerTextWertet in Elementknoten <br> Elemente aus, während textContentSteuerzeichen ausgewertet werden:

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 gibt:

1
2
3
4 5 6 7 8

span.textContent gibt:

1234
5
6
7
8

Zeichenfolgen mit Steuerzeichen (z. B. Zeilenvorschübe) sind nicht verfügbar textContent, wenn der Inhalt mit festgelegt wurde innerText. Umgekehrt (Steuerzeichen setzen mit textContent) werden alle Zeichen sowohl mit innerTextals auch zurückgegeben textContent:

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

Martin Wantke
quelle
20

Beide innerText& textContentsind ab 2016 standardisiert. Alle NodeObjekte (einschließlich Reintextknoten) haben textContent, aber nur HTMLElementObjekte haben innerText.

Funktioniert zwar textContentmit den meisten Browsern, funktioniert jedoch nicht mit IE8 oder früher. Verwenden Sie diese Polyfüllung, damit sie nur unter IE8 funktioniert. Diese Polyfüllung funktioniert nicht mit IE7 oder früher.

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

Die Object.definePropertyMethode ist in IE9 oder höher verfügbar, steht jedoch in IE8 nur für DOM-Objekte zur Verfügung.

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

Richard Hamilton
quelle
2
Hier ist auch die Spezifikation dafür: w3.org/TR/DOM-Level-3-Core/core.html Auch die (sehr alte) Browser-Support-Tabelle ( webdevout.net/browser-support-dom#dom3core ) legt dies nahe Es wird für IE9 + unterstützt, ist also für IE8 und älter innerTextdein Freund.
Geekonaut
Eigentlich ist es eine bessere Idee, entweder ie8 nicht zu unterstützen oder die Polyfüllung zu verwenden. Ich habe die Polyfüllung in meinem Beitrag gepostet
Richard Hamilton
1
Wie kann diese Polyfüllung in IE8 funktionieren, wenn sie nicht unterstützt wird Object.defineProperty()?
Pointy
2
Warum aktualisierst du deine Antwort nicht? html.spec.whatwg.org/multipage/…
caub
3
Hier ist ein Zitat von MDN über innerText: "Diese Funktion wurde ursprünglich von Internet Explorer eingeführt und 2016 im HTML-Standard offiziell spezifiziert, nachdem sie von allen großen Browser-Anbietern übernommen wurde."
Der Chad
15

Für diejenigen, die diese Frage gegoogelt haben und hier angekommen sind. Ich denke, die klarste Antwort auf diese Frage findet sich im MDN-Dokument: https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent .

Sie können alle Punkte vergessen, die Sie verwirren könnten, aber denken Sie an zwei Dinge:

  1. Wenn Sie versuchen, den Text zu ändern, textContentist dies normalerweise die Eigenschaft, nach der Sie suchen.
  2. Wenn Sie versuchen, Text aus einem Element abzurufen, wird innerTextder Text angenähert, den der Benutzer erhalten würde, wenn er den Inhalt des Elements mit dem Cursor hervorhebt und dann in die Zwischenablage kopiert. Und textContentgibt Ihnen alles, sichtbar oder versteckt, einschließlich <script>und <style>Elemente.
Nord
quelle
11

textContent wird von den meisten Browsern unterstützt. Es wird von ie8 oder früher nicht unterstützt, es kann jedoch eine Polyfüllung verwendet werden

Die Eigenschaft textContent legt den Textinhalt des angegebenen Knotens und aller seiner Nachkommen fest oder gibt ihn zurück.

Siehe http://www.w3schools.com/jsref/prop_node_textcontent.asp

Jeremy Ray Brown
quelle
0

textContent gibt Volltext zurück und kümmert sich nicht um die Sichtbarkeit, während innerText dies tut.

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

Ausgabe von textContent:

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

Ausgabe von innerText (beachten Sie, wie innerText Tags wie erkennt <br>und versteckte Elemente ignoriert):

Text with breaking point.
Milan Chandro
quelle
In IE11 entspricht das Verhalten von innerText dem von textContent.
Sebastian
0

Abgesehen von all den Unterschieden, die in den anderen Antworten genannt wurden, ist hier noch einer, den ich erst kürzlich entdeckt habe:

Obwohl die innerTextEigenschaft seit 2016 standardisiert sein soll, weist sie Unterschiede zwischen den Browsern auf: Mozilla ignoriert U + 200E- und U + 200F-Zeichen ("lrm" und "rlm") innerText, Chrome jedoch nicht.

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

Firefox meldet 3 und 2, Chrome meldet 3 und 3.

Ich bin mir noch nicht sicher, ob dies ein Fehler ist (und wenn ja, in welchem ​​Browser) oder nur eine dieser skurrilen Inkompatibilitäten, mit denen wir leben müssen.

Herr Lister
quelle
-1

innerHTML führt sogar die HTML-Tags aus, die gefährlich sein können und jede Art von clientseitigem Injection-Angriff wie DOM-basiertes XSS verursachen. Hier ist das Code-Snippet:

<!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>

Wenn Sie .textContent verwenden, werden die HTML-Tags nicht ausgewertet und als Zeichenfolge gedruckt.

<!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>

Referenz: https://www.scip.ch/en/?labs.20171214

Ashwath Halemane
quelle