Reputation: 281
In the first example, when I append text helloWorldPara1.textContent += 'world';
the class ('red')
applied above, to hello.classList.add('red')
doesn't apply. If I comment out helloWorldPara1.textContent += 'world';
I get hello in red.
In the second example, it seems to work as I applied the class last.
Why can't I append an element with a class then append extra text?
.red{
color: red;
}
<div id="helloWorld1"></div>
<div id="helloWorld2"></div>
// 1. Hello world html div
const helloWorld1 = document.getElementById('helloWorld1');
// Create p
const helloWorldPara1 = document.createElement("p");
// span - hello
const hello = document.createElement("span");
hello.classList.add('red')
hello.textContent = 'hello ';
// Append to Para
helloWorldPara1.appendChild(hello);
// Append text
helloWorldPara1.textContent += 'world'; // Commenting out applies class red to "hello"
// Append p to html div
helloWorld1.appendChild(helloWorldPara1);
// 2. Hello world html div
const helloWorld2 = document.getElementById('helloWorld2');
// Create p
const helloWorldPara2 = document.createElement("p");
// Append text
helloWorldPara2.textContent += 'hello ';
// span - world
const world = document.createElement("span");
world.classList.add('red')
world.textContent = 'world';
// Append to Para
helloWorldPara2.appendChild(world);
// Append p to html div
helloWorld2.appendChild(helloWorldPara2);
Upvotes: 1
Views: 56
Reputation: 56744
Let's take a closer look at what is going on.
At this point
helloWorldPara1.appendChild(hello);
we have this HTML:
<p><span class="red">hello </span></p>
^^^^ ^^^^^
span being a readily parsed HTML element.
Now if you read the textContent
of this <p>
, you will get
"hello "
That is because textContent
, as the name is trying to convey, does only read text, not elements.
When you write to the textContent property of an element, you will effectively delete whatever is between the opening tag and the closing tag, and replace it with whatever you're assigning.
So by doing
helloWorldPara1.textContent += 'world';
You are replacing
<span class="red">hello </span>
by
'hello ' + 'world'
and thus removing your <span class="red">
in the process.
The simplest fix is to work with innerHTML
instead of textContent
, which reads and writes HTML tags as well as the textual content.
This would be a bad solution for security and performance reasons, so the best way is to create the text you want to append just like you created the p
and the span
, with the help of document.createTextNode()
:
// 1. Hello world html div
const helloWorld1 = document.getElementById('helloWorld1');
// Create p
const helloWorldPara1 = document.createElement("p");
// span - hello
const hello = document.createElement("span");
hello.classList.add('red')
hello.textContent = 'hello ';
// Append to Para
helloWorldPara1.appendChild(hello);
// Append text
helloWorldPara1.appendChild(document.createTextNode('world'))
// Append p to html div
helloWorld1.appendChild(helloWorldPara1);
.red {
color: red;
}
<div id="helloWorld1"></div>
<div id="helloWorld2"></div>
Upvotes: 2