Diferença entre textContent vs innerText

156

Qual é a diferença entre textContente innerTextem JavaScript?

Posso usar da textContentseguinte maneira:

var logo$ = document.getElementsByClassName('logo')[0];
logo$.textContent = "Example";
JK
fonte
3
Eles são iguais, mas alguns navegadores suportam um e outros o outro.
Pointy
@ Pointy, qual é o suporte de todos os navegadores?
Yehia Awad
6
Uma boa publicação no blog sobre isso #
Tyblitz 04/04
4
@ Pointy, consulte a postagem do blog que apontei. Sua declaração está incorreta, há uma diferença.
Tyblitz 04/02
3
innerTexte textContentdecididamente não são os mesmos. Ocorrências de espaço em branco no conteúdo do nó farão com que as duas propriedades produzam conteúdo diferente, assim como ocorrências de brelementos e outros descendentes renderizados no nível do bloco.
01:

Respostas:

211

Nenhuma das outras respostas consegue fornecer a explicação completa, daí esta. As principais diferenças entre innerTexte textContentestão descritas muito bem no blog de Kelly Norton: innerText vs. textContent . Abaixo você pode encontrar um resumo:

  1. innerTextnão era padrão, enquanto textContentera padronizado anteriormente.
  2. innerTextretorna o texto visível contido em um nó, enquanto textContentretorna o texto completo . Por exemplo, no seguinte HTML<span>Hello <span style="display: none;">World</span></span> , innerTextretornará 'Hello', enquanto textContentretornará 'Hello World'. Para obter uma lista mais completa das diferenças, consulte a tabela em http://perfectionkills.com/the-poor-misunderstood-innerText/ (a leitura adicional em 'innerText' funciona no IE, mas não no Firefox ).
  3. Como resultado, innerTexttem muito mais desempenho: requer informações de layout para retornar o resultado.
  4. innerText é definido apenas para HTMLElement objetos, enquanto textContenté definido para todos os Nodeobjetos.

Uma solução alternativa para o textContentIE8- envolveria uma função recursiva usando nodeValueem todo childNodeso nó especificado. Aqui está uma tentativa em um 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;
}
Tyblitz
fonte
16
Também digno de nota: innerTexttransformará <br>elementos em caracteres de nova linha, enquanto textContentos ignorará. Então 2 palavras com apenas uma <br>elemento entre eles (e sem espaços) serão concatenados ao usartextContent
skerit
5
Existe alguma diferença quando o setter é usado? Como elem.textContent = 'foobar'vselem.innerText = 'foobar'
Franklin Yu
1
Outra diferença de comportamento entre innerTexte textContent: Se você alterar o text-transformelemento de um CSS, ele afetará o resultado de 'innerText', mas não o resultado de textContent. Por exemplo: innerTextof <div style="text-transform: uppercase;">Hello World</div>será "HELLO WORLD", enquanto textContentserá "Hello World".
Kobi
25

textContent é o único disponível para nós de texto:

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

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

Nos nós do elemento, innerTextavalia <br> elementos, enquanto textContentavalia caracteres de controle:

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

Seqüências de caracteres com caracteres de controle (por exemplo, feeds de linha) não estarão disponíveis textContentse o conteúdo tiver sido definido com innerText. Por outro lado (definir caracteres de controle com textContent), todos os caracteres são retornados com innerTexte textContent:

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

Martin Wantke
fonte
20

Ambos innerText& textContentsão padronizados a partir de 2016. Todos os Nodeobjetos (incluindo os nós de texto puro) têm textContent, mas apenas HTMLElementobjetos têm innerText.

Embora textContentfuncione com a maioria dos navegadores, ele não funciona no IE8 ou anterior. Use esse polyfill para funcionar apenas no IE8. Esse polyfill não funcionará com o IE7 ou anterior.

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

o Object.defineProperty método está disponível no IE9 ou superior, no entanto, está disponível no IE8 apenas para objetos 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

Richard Hamilton
fonte
2
Aqui também está a especificação: w3.org/TR/DOM-Level-3-Core/core.html Também a tabela (muito antiga) de suporte ao navegador ( webdevout.net/browser-support-dom#dom3core ) sugere que é compatível com o IE9 +, portanto, para o IE8 e mais antigo, innerTexté seu amigo.
Geekonaut
Na verdade, é melhor não apoiar o ie8 ou usar o polyfill. Eu publiquei o polyfill no meu post
Richard Hamilton
1
Como esse polyfill funciona no IE8 quando não é compatível Object.defineProperty()?
Pointy
2
por que você não atualiza sua resposta? html.spec.whatwg.org/multipage/…
caub
3
Aqui está uma citação da MDN sobre innerText - "Esse recurso foi originalmente introduzido pelo Internet Explorer e foi formalmente especificado no padrão HTML em 2016 após ser adotado por todos os principais fornecedores de navegadores".
the chad
15

Para quem pesquisou esta questão e chegou aqui. Sinto que a resposta mais clara para essa pergunta está no documento MDN: https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent .

Você pode esquecer todos os pontos que podem confundi-lo, mas lembre-se de duas coisas:

  1. Quando você está tentando alterar o texto, textContent geralmente é a propriedade que você está procurando.
  2. Quando você está tentando pegar texto de algum elemento, innerTextaproxima o texto que o usuário obteria se destacasse o conteúdo do elemento com o cursor e depois copiasse para a área de transferência. E textContentfornece tudo, visível ou oculto, incluindo <script>e <style>elementos.
Norte
fonte
11

textContent é suportado pela maioria dos navegadores. Não é suportado pelo ie8 ou anterior, mas um polyfill pode ser usado para esse

A propriedade textContent define ou retorna o conteúdo textual do nó especificado e todos os seus descendentes.

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

Jeremy Ray Brown
fonte
0

textContent retorna texto completo e não se preocupa com a visibilidade, enquanto innerText sim.

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

Saída de textContent:

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

Saída de innerText (observe como innerText está ciente de tags como <br>e ignora o elemento oculto):

Text with breaking point.
Milan Chandro
fonte
No IE11, o comportamento do innerText é o mesmo do textContent.
Sebastian
0

Além de todas as diferenças que foram nomeadas nas outras respostas, aqui está outra que eu descobri recentemente:

Embora se innerTextdiga que a propriedade foi padronizada desde 2016, ela exibe diferenças entre os navegadores: o Mozilla ignora os caracteres U + 200E e U + 200F ("lrm" e "rlm") innerText, enquanto o Chrome não.

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

O Firefox relata 3 e 2, o Chrome relata 3 e 3.

Ainda não tenho certeza se isso é um bug (e se sim, em qual navegador) ou apenas uma daquelas incompatibilidades peculiares com as quais temos que conviver.

Mr Lister
fonte
-1

innerHTML executará até as tags HTML que podem ser perigosas, causando qualquer tipo de ataque de injeção no cliente, como o XSS baseado em DOM. Aqui está o trecho de código:

<!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 você usar .textContent, ele não avaliará as tags HTML e as imprimirá como String.

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

Referência: https://www.scip.ch/en/?labs.20171214

Ashwath Halemane
fonte