Ending the Battle between innerHTML and textContent, Once and for All
Published: 2023-01-04 06:06:29

It's the day of your first official coding challenge at Flatiron School. You've done your prep, got 8 hours of Z's, and ate a bacon egg 'n' cheese for fuel. You're ready...

And, somehow, you manage to pass! You're proud - you were one of a few to actually pull it off. Pat yourself on the back for a job well done. Every day, at times like this, you feel that imposter syndrome fading juuuust a little more.

*...Of course, it could've been better.*

That's what I quickly realized once my instructor began his review of the challenge we'd just undertaken. There were many areas I could've optimized my code, but I'd not been able to come up with them in time. I want to go over one of them that only really clicked once I saw it in action during this very review: innerHTML, and when to use it instead of textContent.

First, let's go over textContent, since I'd been exclusively been using that to manipulate the, uh... text content... for lack of a better term. This is a property of nodes in the DOM that we can manipulate in JS, kind of like this:

<div class="aside">
exampleNode.textContent = "Wow! I'm so good at this!";
</div>

If we have a node that can contain text, like an h1 or a p, then we can use textContent to assign a string as the value of that node. Let's say exampleNode is a variable pointing to an h1 tag. Now, between the opening and closing tags, we'll see the text "Wow! I'm so good at this!", and on your page, you'll see that message in giant lettering. We've altered the *text content* of the h1 tag. See how that works?

But, what if we used innerHTML instead? What if we'd said:

<div class="aside">
exampleNode.innerHTML = "Wow! I'm also good at this!";
</div>

Believe it or not, this is going to have the same effect. So then innerHTML and textContent must be the same thing, right? For a moment, I'd thought so too. However, consider this:

<div class="aside">
    <ul id="unwanted-list">
        <li>I'm first!</li>
        <li>First is the worst, second is the best!</li>
    </ul>
</div>

Say you want to remove those pesky list elements and add in some new ones. Maybe you've asked an API nicely, and it's graciously given you some information that you want to display in this list. How will you go about this?

I know! Let's try textContent! We can assign the text of the unordered list element to an empty string! Easy peasy, right?

const unwantedUnorderedList = document.getElementById("unwanted-list");
unwantedUnorderedList.textContent = "";

Seems to have worked, right? Well... not quite. After executing this line, the list elements still remain. Not what we were going for. Still, maybe we can try innerHTML?

unwantedUnorderedList.innerHTML = "";

It worked! The list elements are gone, and we're free to add new ones as we please. Still, why would this work, but not textContent?

Well, it's actually laughably simple. The textContent refers to an element's, um... text content. And - stay with me here - the innerHTML refers to its inner HTML, meaning both tags and text (tags and text being basically all that make up HTML). The textContent excludes tags themselves, but the innerHTML includes them.

Well, you could be wondering how exactly this tripped me up. Honestly, it's because I'd forgotten innerHTML existed! And I was, in fact, getting information from an API to display within an unordered list. With no knowledge of innerHTML's existence, I didn't know I could remove the tags. So, I thought a little outside the box: I used a while loop to assign each li element's text content a string containing information from the index matching the current value of the counter variable I used for the loop. Once all the li elements had text, there remained more information to display, so I spliced the remaining info from the original fetch response into a new array, and for each index I added a new li element containing the necessary info to the unordered list.

SIMPLE!

Sure, I'd made it work out in the end, but take it from me: knowing the difference between these two properties could end up saving you lots of time Happy coding, young padawan.