Difference between textContent vs innerText

101,011

Solution 1

The key differences between innerText and textContent are outlined very well in Kelly Norton's blogpost: innerText vs. textContent. Below you can find a summary:

  1. innerText was non-standard, textContent was standardized earlier.
  2. innerText returns the visible text contained in a node, while textContent returns the full text. For example, on the following HTML <span>Hello <span style="display: none;">World</span></span>, innerText will return 'Hello', while textContent will return 'Hello World'. For a more complete list of differences, see the table at http://perfectionkills.com/the-poor-misunderstood-innerText/ (further reading at 'innerText' works in IE, but not in Firefox).
  3. As a result, innerText is much more performance-heavy: it requires layout information to return the result.
  4. innerText is defined only for HTMLElement objects, while textContent is defined for all Node objects.

Be sure to also have a look at the informative comments below this answer.

textContent was unavailable in IE8-, and a bare-metal polyfill would have looked like a recursive function using nodeValue on all childNodes of the specified node:

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

Solution 2

textContent is the only one available for text nodes:

var text = document.createTextNode('text');
console.log(text.innerText);    //  undefined
console.log(text.textContent);  //  text

In element nodes, innerText evaluates <br> elements, while textContent evaluates control characters:

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

1
2
3
4 5 6 7 8

span.textContent gives:

1234
5
6
7
8

Strings with control characters (e. g. line feeds) are not available with textContent, if the content was set with innerText. The other way (set control characters with textContent), all characters are returned both with innerText and textContent:

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

Solution 3

For those who googled this question and arrived here. I feel the most clear answer to this question is in MDN document: https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent.

You can forgot all the points that may confuse you but remember 2 things:

  1. When you are trying to alter the text, textContent is usually the property you are looking for.
  2. When you are trying to grab text from some element, innerText approximates the text the user would get if they highlighted the contents of the element with the cursor and then copied to the clipboard. And textContent gives you everything, visible or hidden, including <script> and <style> elements.

Solution 4

Both innerText & textContent are standardized as of 2016. All Node objects (including pure text nodes) have textContent, but only HTMLElement objects have innerText.

While textContent works with most browsers, it does not work on IE8 or earlier. Use this polyfill for it to work on IE8 only. This polyfill will not work with IE7 or earlier.

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

The Object.defineProperty method is availabe in IE9 or up, however it is available in IE8 for DOM objects only.

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

Solution 5

textContent is supported by most browsers. It is not supported by ie8 or earlier, but a polyfill can be used for this

The textContent property sets or returns the textual content of the specified node, and all its descendants.

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

Share:
101,011

Related videos on Youtube

J K
Author by

J K

Updated on September 16, 2021

Comments

  • J K
    J K about 1 year

    What is the difference between textContent and innerText in JavaScript?

    Can I use textContent as follows:

    var logo$ = document.getElementsByClassName('logo')[0];
    logo$.textContent = "Example";
    
    • Yehia Awad
      Yehia Awad almost 7 years
      @Pointy what is the one that all browsers support?
    • webketje
      webketje almost 7 years
      A good blog post about it
    • webketje
      webketje almost 7 years
      @Pointy please refer to the blog post I pointed to. Your statement is incorrect, there is a difference.
    • Armen Michaeli
      Armen Michaeli over 3 years
      innerText and textContent are decidedly not the same. White-space occurences in node content will cause the two properties yield different content, and so will occurences of br elements and other block-level rendered descendants.
  • geekonaut
    geekonaut almost 7 years
    Here's the spec for it, too: w3.org/TR/DOM-Level-3-Core/core.html Also the (very old) browser support table (webdevout.net/browser-support-dom#dom3core) suggests, that it's supported for IE9+, so for IE8 and older, innerText is your friend.
  • Richard Hamilton
    Richard Hamilton almost 7 years
    Actually, it's a better idea to either not support ie8 or use the polyfill. I posted the polyfill in my post
  • Pointy
    Pointy almost 7 years
    How can that polyfill work in IE8 when it didn't support Object.defineProperty()?
  • Richard Hamilton
    Richard Hamilton almost 7 years
    Just took a look at the MDN documentation. It says this In Internet Explorer 8 only on DOM objects and with some non-standard behaviors.
  • caub
    caub almost 5 years
    why don't you update your answer? html.spec.whatwg.org/multipage/…
  • Jelle De Loecker
    Jelle De Loecker over 4 years
    Also worth noting: innerText will turn <br> elements into newline characters, while textContent will just ignore them. So 2 words with only a <br> element between them (and no spaces) will be concatenated when using textContent
  • Franklin Yu
    Franklin Yu almost 4 years
    Then is there any difference when the setter is used? Like elem.textContent = 'foobar' v.s. elem.innerText = 'foobar'
  • the chad over 3 years
    Here is a quote from MDN about innerText - "This feature was originally introduced by Internet Explorer, and was formally specified in the HTML standard in 2016 after being adopted by all major browser vendors."
  • Sebastian about 3 years
    In IE11, the behavior of innerText is the same as the one of textContent.
  • Kobi almost 3 years
    Another difference in behavior between innerText and textContent: If you change the text-transform of an element by CSS, it will affect the result of 'innerText', but not the result of textContent. For example: innerText of <div style="text-transform: uppercase;">Hello World</div> will be "HELLO WORLD", while textContent will be "Hello World".
  • AndrewF
    AndrewF about 2 years
    The question did not mention innerHTML. The answer did not mention innerText.
  • Shimon S
    Shimon S about 2 years
    Regarding to point "3" (performance). I did a quick test and I don't see that it's true. let allElements = [...document.getElementsByTagName('*')]; t1 = performance.now(); for(let i=0; i<allElements.length; i++){ txt = allElements[i].innerText; } t2 = performance.now(); console.log('innerText', t2-t1); for(let i=0; i<allElements.length; i++){ txt = allElements[i].textContent; } t3 = performance.now(); console.log('textContent', t3-t2); Execute it in console and see. In some cases (on this site, for example) textContent is a little better, on mail.google.com - vice versa.
  • webketje
    webketje about 2 years
    @ShimonS innerText is much more performance-heavy is true, but is to be taken relatively: if innerText is 100x slower than textContent on avg, and textContent takes 1/1000 of a millisecond per op, 1/10th of a millisecond will still feel fast to humans. Furthermore a meaningful comparison between the 2 can only be one where the element contains a lot of hidden stuff like <script> or style="display: none;" children
  • m4n0
    m4n0 about 1 year
    Is there any innertextContent?
  • CennoxX
    CennoxX 8 months
    @m4n0 no, I've corrected the answer

Related