Differenza tra textContent e innerText


157

Qual è la differenza tra textContente innerTextin JavaScript?

Posso usare textContentcome segue:

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

3
Sono uguali, ma alcuni browser supportano l'uno e altri l'altro.
Punta a punta

@Pointy qual è quello supportato da tutti i browser?
Yehia Awad,

6
Un buon post sul blog a riguardo
Tyblitz

4
@Pointy si prega di fare riferimento al post sul blog che ho indicato. La tua affermazione è errata, c'è una differenza.
Tyblitz,

3
innerTexte textContentdecisamente non sono gli stessi. Le occorrenze di spazi vuoti nel contenuto del nodo causeranno un diverso contenuto delle due proprietà, così come le occorrenze di brelementi e altri discendenti renderizzati a livello di blocco.
AMN

Risposte:


211

Nessuna delle altre risposte riesce a fornire la spiegazione completa, quindi questa. Le differenze chiave tra innerTexte textContentsono delineate molto bene nel blogpost di Kelly Norton: innerText vs. textContent . Di seguito puoi trovare un riepilogo:

  1. innerTextera non standard, mentre textContentera standardizzato in precedenza.
  2. innerTextrestituisce il testo visibile contenuto in un nodo, mentre textContentrestituisce il testo completo . Ad esempio, sul seguente codice HTML <span>Hello <span style="display: none;">World</span></span>, innerTextverrà restituito "Hello", mentre textContentverrà restituito "Hello World". Per un elenco più completo delle differenze, consultare la tabella su http://perfectionkills.com/the-poor-misunderstood-innerText/ (ulteriori letture su 'innerText' funzionano in IE, ma non in Firefox ).
  3. Di conseguenza, innerTextè molto più performante: richiede informazioni sul layout per restituire il risultato.
  4. innerTextè definito solo per gli HTMLElementoggetti, mentre textContentè definito per tutti gli Nodeoggetti.

Una soluzione alternativa per textContentin IE8- implicherebbe una funzione ricorsiva usando nodeValuesu tutto childNodesil nodo specificato, ecco un tentativo in un 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
Vale anche la pena notare: innerTexttrasformerà gli <br>elementi in caratteri di nuova riga, mentre textContentli ignorerà. Quindi 2 parole con solo un <br>elemento tra loro (e senza spazi) saranno concatenate quando si utilizzatextContent
skerit

5
Quindi c'è qualche differenza quando si usa il setter? Come elem.textContent = 'foobar'vselem.innerText = 'foobar'
Franklin Yu,

1
Un'altra differenza di comportamento tra innerTexte textContent: se si modifica l' text-transformelemento di un elemento tramite CSS, ciò influirà sul risultato di "innerText", ma non sul risultato di textContent. Ad esempio: innerTextof <div style="text-transform: uppercase;">Hello World</div>sarà "HELLO WORLD", mentre textContentsarà "Hello World".
Kobi,

25

textContent è l'unico disponibile per i nodi di testo:

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

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

Nei nodi degli elementi, innerTextvaluta gli elementi, mentre textContentvaluta i caratteri di controllo:

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 dà:

1
2
3
4 5 6 7 8

span.textContent dà:

1234
5
6
7
8

Le stringhe con caratteri di controllo (ad esempio feed di riga) non sono disponibili con textContent, se il contenuto è stato impostato con innerText. Altrimenti (imposta i caratteri di controllo con textContent), tutti i caratteri vengono restituiti sia con innerTextche textContent:

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


20

Entrambi innerTexte textContentsono standardizzati a partire dal 2016. Tutti gli Nodeoggetti (compresi i nodi di testo puro) hanno textContent, ma solo gli HTMLElementoggetti innerText.

Sebbene textContentfunzioni con la maggior parte dei browser, non funziona su IE8 o versioni precedenti. Usa questo polyfill per farlo funzionare solo su IE8. Questo polyfill non funzionerà con IE7 o versioni precedenti.

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

Il Object.definePropertymetodo è disponibile in IE9 o versioni successive, tuttavia è disponibile in IE8 solo per oggetti 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
Ecco anche le specifiche: w3.org/TR/DOM-Level-3-Core/core.html Anche la tabella di supporto del browser (molto vecchia) ( webdevout.net/browser-support-dom#dom3core ) suggerisce che è supportato per IE9 +, quindi per IE8 e versioni precedenti innerTextè tuo amico.
geekonaut

In realtà, è un'idea migliore non supportare ie8 o utilizzare il polyfill. Ho pubblicato il polyfill nel mio post
Richard Hamilton,

1
Come può quel polyfill funzionare in IE8 quando non supporta Object.defineProperty()?
Punta il

2
perché non aggiorni la tua risposta? html.spec.whatwg.org/multipage/…
caub

3
Ecco una citazione di MDN su innerText - "Questa funzione è stata originariamente introdotta da Internet Explorer ed è stata formalmente specificata nello standard HTML nel 2016 dopo essere stata adottata da tutti i principali fornitori di browser".
il ciad

15

Per chi ha cercato su Google questa domanda ed è arrivato qui. Ritengo che la risposta più chiara a questa domanda sia nel documento MDN: https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent .

Puoi dimenticare tutti i punti che potrebbero confonderti, ma ricorda 2 cose:

  1. Quando si tenta di modificare il testo, di textContentsolito è la proprietà che si sta cercando.
  2. Quando si sta tentando di afferrare del testo da un elemento, innerTextapprossima il testo che l'utente otterrebbe se evidenziasse il contenuto dell'elemento con il cursore e quindi lo copiasse negli Appunti. E textContentti dà tutto, visibile o nascosto, compresi <script>e gli <style>elementi.


0

textContent restituisce il testo completo e non si preoccupa della visibilità, mentre innerText lo fa.

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

Output di textContent:

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

Output di innerText (nota come innerText è a conoscenza di tag simili <br>e ignora l'elemento nascosto):

Text with breaking point.

In IE11, il comportamento di innerText è lo stesso di textContent.
Sebastian,

0

A parte tutte le differenze che sono state nominate nelle altre risposte, eccone un'altra che ho scoperto solo di recente:

Anche se innerTextsi dice che la proprietà sia stata standardizzata dal 2016, mostra differenze tra i browser: Mozilla ignora i caratteri U + 200E e U + 200F ("lrm" e "rlm") innerText, mentre Chrome non lo fa.

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

Firefox segnala 3 e 2, Chrome segnala 3 e 3.

Non sono ancora sicuro se questo è un bug (e in tal caso, in quale browser) o solo una di quelle incompatibilità bizzarre con cui dobbiamo convivere.


-1

innerHTML eseguirà anche i tag HTML che potrebbero essere pericolosi causando qualsiasi tipo di attacco di iniezione lato client come XSS basato su DOM. Ecco il frammento di codice:

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

Se si utilizza .textContent, non valuterà i tag HTML e non verrà stampato come stringa.

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

Riferimento: https://www.scip.ch/it/?labs.20171214

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.