JavaScript innerHTML, innerText, and textContent
Tags: javascript, html, ux, security
Published: 2020-01-17 20:44:28

In Javascript, there are three properties that can be used to set or return an HTML element's content in the DOM: innerHTML, innerText, and textContent. If you are unsure about the differences and wondering which one to use, hopefully the following comparison will help.

**(1)** The **innerHTML** property sets and returns the content of an element with new HTML content. 

```javascript
// Setting text with innerHTML:
const example = document.getElementById('example')
example.innerHTML = "<p>This is <strong>my</strong> paragraph.</p>"
```

Although HTML5 prevents a `<script>` tag inserted with innerHTML from executing, there is still a security risk whenever you use innerHTML to set strings using Javascript. Cybercriminals can embed Javascript code without using `<script>` to rewrite content in the HTML page or redirect the browser to another page with malicious code. Due to this reason, **it is NOT recommended to use innerHTML when inserting plain text.**


To learn more about innerHTML and Cross-Site Scripting (XSS) attacks, refer to the resources links at the end of this post.


```javascript
// HTML5 prevents malicious <script> from executing:
// alert WILL NOT show
const example1 = "<script>alert('I am an annoying alert!')</script>"
el.innerHTML = example1 

const example2 = document.getElementById('example2')
example2.innerHTML = '<script deferred>alert("XSS Attack");</script>'


// Examples of cybercriminals embedding Javascript without <script>:
// alert WILL show
const example3 = "<img src='x' onerror='alert(1)'>"
el.innerHTML = example3 

const example4 = document.getElementById('example4')
example4.innerHTML = '<img src=x onerror="alert(\'XSS Attack\')">'

<img src=j&#X41vascript:alert('test2')>

<img src="http://url.to.file.which/not.exist" onerror=alert(document.cookie);>

<button onmouseover=alert('Wufff!')>click me!</button>
```

<br>
**(2)** The **innerText** property returns the content of all elements, except for `<script>` and `<style>` elements. The returned content is visible plain text without any formatting, similar to highlighting text and then copying and pasting it. What you see is what you get. 

One drawback to using innerText is that its value triggers a reflow due to its awareness of CSS styling, which leads to decreased performance. Reflow is when the browser recalculates page elements for re-rendering the document. Instances that trigger reflow include resizing the browser window or changing elements in the DOM. Reflow is computationally expensive and should be minimized in order to improve speed, efficiency, and user experience.
 

<small>NOTE: The innerText property is not supported in Internet Explorer 9 and earlier.</small>
```javascript
// Setting text with innerText:
const example = document.getElementById('example')
example.innerText = "text"
```

<br>
**(3)** The **textContent** property returns the raw content with styling inside of all elements, but excludes the HTML element tags. This includes `<script>` and `<style>` elements, whitespace, line breaks, and carriage returns. Unlike innerHTML, textContent has better performance because its value is not parsed as HTML. For that reason, using textContent can also prevent Cross-Site Scripting (XSS) attacks. Unlike innerText, textContent isn't aware of CSS styling and will not trigger a reflow. All Node objects have textContent, whereas only HTMLElement objects have innerText.


<small>NOTE: The textContent property is not supported in Internet Explorer 8 and earlier.</small>

```javascript
// Setting text with textContent:
const example = document.getElementById('example')
example.textContent = "word"
```


<br>
**The example below shows how each of the three properties return the contents of the `<p>` element:**
```html
<p id="demo"> This element has extra spacing   and contains <span>a span element</span>.
</p>
```

```javascript
function getInnerHtml() {
  console.log(document.getElementById("demo").innerHTML)
}

innerHTML returns: 
" This element has extra spacing   and contains <span>a span element</span>."
/* 
The innerHTML property returns the text, spacing, and inner HTML element tags.
*/



function getInnerText() {
  console.log(document.getElementById("demo").innerText)
}

innerText returns: 
"This element has extra spacing and contains a span element."
/* 
The innerText property returns just the visible text, 
without spacing or inner HTML element tags.
*/



function getTextContent() {
  console.log(document.getElementById("demo").textContent)
}

textContent returns: 
" This element has extra spacing   and contains a span element."
/* 
The textContent property returns the text and spacing, 
but without the inner HTML element tags.
*/
```

Now that you know the differences between all the available options for returning and setting text in Javascript, use the one that best fits your content needs.


**Resources:**
<small>https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML
https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent#Differences_from_innerText
http://perfectionkills.com/the-poor-misunderstood-innerText/
https://kellegous.com/j/2013/02/27/innertext-vs-textcontent/
https://developers.google.com/speed/docs/insights/browser-reflow
https://frontendmasters.com/courses/web-performance/layouts-and-reflows/
https://developer.mozilla.org/en-US/docs/Glossary/Cross-site_scripting
https://www.owasp.org/index.php/Cross-site_Scripting_(XSS)
</small>