Diferencia entre textContent vs innerText


157

¿Cuál es la diferencia entre textContenty innerTexten JavaScript?

¿Puedo usar textContentlo siguiente:

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

3
Son lo mismo, pero algunos navegadores admiten uno y otros el otro.
Puntiagudo

@Pointy, ¿cuál es el que admiten todos los navegadores?
Yehia Awad


44
@Pointy, consulte la publicación de blog que señalé. Su declaración es incorrecta, hay una diferencia.
Tyblitz

3
innerTexty textContentdecididamente no son lo mismo. Las ocurrencias de espacios en blanco en el contenido del nodo harán que las dos propiedades produzcan contenido diferente, y también lo harán las ocurrencias de brelementos y otros descendientes representados a nivel de bloque.
amn

Respuestas:


211

Ninguna de las otras respuestas tiene éxito en proporcionar la explicación completa, de ahí esta. Las diferencias clave entre innerTextytextContent se describen muy bien en la publicación de blog de Kelly Norton: innerText vs. textContent . A continuación puede encontrar un resumen:

  1. innerTextno era estándar, mientras que textContentse estandarizó antes.
  2. innerTextdevuelve el texto visible contenido en un nodo, mientras que textContentdevuelve el texto completo . Por ejemplo, en el siguiente HTML <span>Hello <span style="display: none;">World</span></span>, innerTextdevolverá 'Hola', mientras textContentque devolverá 'Hola mundo'. Para obtener una lista más completa de las diferencias, consulte la tabla en http://perfectionkills.com/the-poor-misunderstood-innerText/ (la lectura adicional en 'innerText' funciona en IE, pero no en Firefox ).
  3. Como resultado, innerTextrequiere mucho más rendimiento: requiere información de diseño para devolver el resultado.
  4. innerTextse define solo para HTMLElementobjetos, mientras que textContentse define para todos los Nodeobjetos.

Una solución alternativa para textContentIE8 implicaría una función recursiva nodeValueen todos childNodeslos nodos especificados, aquí hay una prueba en 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
También vale la pena señalar: innerTextconvertirá los <br>elementos en caracteres de nueva línea, mientras textContentque los ignorará. Por lo tanto, 2 palabras con solo un <br>elemento entre ellas (y sin espacios) se concatenarán cuando se usetextContent
skerit

55
Entonces, ¿hay alguna diferencia cuando se usa el setter? Like elem.textContent = 'foobar'vselem.innerText = 'foobar'
Franklin Yu

1
Otra diferencia en el comportamiento entre innerTexty textContent: si cambia el text-transformelemento de un elemento por CSS, afectará el resultado de 'innerText', pero no el resultado de textContent. Por ejemplo: innerTextde <div style="text-transform: uppercase;">Hello World</div>será "HOLA MUNDO", mientras textContentque será "Hola Mundo".
Kobi

25

textContent es el único disponible para nodos de texto:

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

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

En los nodos de elementos, innerTextevalúa <br> elementos, mientras textContentevalúa los caracteres de control:

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

1
2
3
4 5 6 7 8

span.textContent da:

1234
5
6
7
8

Las cadenas con caracteres de control (p. Ej., Saltos de línea) no están disponibles con textContent, si el contenido se configuró con innerText. A la inversa (establecer caracteres de control con textContent), todos los caracteres se devuelven con innerTexty textContent:

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


20

Tanto innerTexty textContentestán estandarizados a partir de 2016. Todos los Nodeobjetos (incluyendo los nodos de texto puro) tienen textContent, pero sólo los HTMLElementobjetos tienen innerText.

Si bien textContentfunciona con la mayoría de los navegadores, no funciona en IE8 o versiones anteriores. Use este polyfill para que funcione solo en IE8. Este polyfill no funcionará con IE7 o versiones anteriores.

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

El Object.definePropertymétodo está disponible en IE9 o superior, sin embargo, está disponible en IE8 solo 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


2
Aquí también está la especificación: w3.org/TR/DOM-Level-3-Core/core.html También la (muy antigua) tabla de soporte del navegador ( webdevout.net/browser-support-dom#dom3core ) sugiere que es compatible con IE9 +, por lo que para IE8 y anteriores, innerTextes tu amigo.
geekonaut

En realidad, es una mejor idea no admitir ie8 o usar el polyfill. Publiqué el polyfill en mi publicación
Richard Hamilton

1
¿Cómo puede funcionar ese polyfill en IE8 cuando no es compatible Object.defineProperty()?
Puntiagudo

2
¿Por qué no actualizas tu respuesta? html.spec.whatwg.org/multipage/…
caub

3
Aquí hay una cita de MDN sobre innerText: "Esta característica fue introducida originalmente por Internet Explorer y se especificó formalmente en el estándar HTML en 2016 después de ser adoptada por todos los principales proveedores de navegadores".
el chad

15

Para aquellos que buscaron en Google esta pregunta y llegaron aquí. Siento que la respuesta más clara a esta pregunta está en el documento MDN: https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent .

Puedes olvidar todos los puntos que pueden confundirte, pero recuerda 2 cosas:

  1. Cuando intentas alterar el texto, textContent generalmente es la propiedad que está buscando.
  2. Cuando intentas tomar texto de algún elemento, innerText aproxima al texto que obtendría el usuario si resaltara el contenido del elemento con el cursor y luego lo copiara al portapapeles. Y textContentle da todo, visibles u ocultos, incluyendo <script>y <style>elementos.


0

textContent devuelve texto completo y no le importa la visibilidad, mientras que innerText sí.

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

Salida de contenido de texto:

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

Salida de innerText (observe cómo innerText es consciente de las etiquetas como <br>, e ignora el elemento oculto):

Text with breaking point.

En IE11, el comportamiento de innerText es el mismo que el de textContent.
Sebastian

0

Además de todas las diferencias que se mencionaron en las otras respuestas, aquí hay otra que descubrí recientemente:

Aunque innerTextse dice que la propiedad ha sido estandarizada desde 2016, exhibe diferencias entre los navegadores: Mozilla ignora los caracteres U + 200E y U + 200F ("lrm" y "rlm") innerText, mientras que Chrome no.

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

Firefox informa 3 y 2, Chrome informa 3 y 3.

Todavía no estoy seguro si esto es un error (y si es así, en qué navegador) o solo una de esas incompatibilidades peculiares con las que tenemos que vivir.


-1

innerHTML ejecutará incluso las etiquetas HTML que pueden ser peligrosas y causar cualquier tipo de ataque de inyección del lado del cliente como XSS basado en DOM. Aquí está el fragmento 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>

Si usa .textContent, no evaluará las etiquetas HTML e 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>

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

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.