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";
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";
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:
innerText
was non-standard, textContent
was standardized earlier.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).innerText
is much more performance-heavy: it requires layout information to return the result.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;
}
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
–
Moonier elem.textContent = 'foobar'
v.s. elem.innerText = 'foobar'
–
Snoop 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". –
Karolekarolina 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. –
Sticker 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 –
Chainsmoke textContent
is infinitely better. #72875015 –
Mistiemistime 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
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:
textContent
is usually the property you are looking for.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.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/API/Node/textContent
innerText
is your friend. –
Bargainbasement Object.defineProperty()
? –
Lavolta In Internet Explorer 8 only on DOM objects and with some non-standard behaviors.
–
Schreibman 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
Aside from all the differences that were named in the other answers, here is another one which I discovered only recently:
Even though the innerText
property is said to've been standardised since 2016, it exhibits differences between browsers: Mozilla ignores U+200E and U+200F characters ("lrm" and "rlm") in innerText
, while Chrome does not.
console.log(document.getElementById('test').textContent.length);
console.log(document.getElementById('test').innerText.length);
<div id="test">[‎]</div>
Firefox reports 3 and 2, Chrome reports 3 and 3.
Not sure yet if this is a bug (and if so, in which browser) or just one of those quirky incompatibilities which we have to live with.
textContent
returns full text and does not care about visibility, while innerText
does.
<p id="source">
<style>#source { color: red; }</style>
Text with breaking<br>point.
<span style="display:none">HIDDEN TEXT</span>
</p>
Output of textContent
:
#source { color: red; } Text with breakingpoint. HIDDEN TEXT
Output of innerText
( note how innerText
is aware of tags like <br>
, and ignores hidden element ):
Text with breaking point.
Another useful behavior of innerText
compared to textContent
is that newline characters and multiple spaces next to each other will be displayed as one space only, which can be easier to compare a string.
But depending on what you want, firstChild.nodeValue
may be enough.
document.querySelector('h1').innerText/innerHTML/textContent
.querySelector('h1').innerText
- gives us text inside. It sensitive to what is currently being displayed or staff that's being hidden is ignored.
.querySelector('h1').textContent
- it's like innerText
but it does not care about what is being displayed or what's actually showing to user. It will show all.
.querySelector('h1').innerHTML
= <i>sdsd</i>
Will work* - retrieves full contents, including the tag names.
innerHTML will execute even the HTML tags which might be dangerous causing any kind of client-side injection attack like DOM based XSS. Here is the 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>
If you use .textContent, it will not evaluate the HTML tags and print it as 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>
Reference: https://www.scip.ch/en/?labs.20171214
innerHTML
. The answer did not mention innerText
. –
Substrate © 2022 - 2024 — McMap. All rights reserved.
.text()
method is your friend here: api.jquery.com/text – ThoseinnerText
is because there's no choice on older IE versions. – LavoltainnerText
andtextContent
are decidedly not the same. White-space occurences in node content will cause the two properties yield different content, and so will occurences ofbr
elements and other block-level rendered descendants. – HerewithinnerText
as setter turns\n
into<br>
. I was aware of the other direction in the getter, but I had not expected that markup is produced when setting text. FortextContent
this is of course not the case. – Militarize