3

I've been learning about javascript and childnodes. For an exercise, we have to switch the text of listitems to uppercase through the use of a parent node.

Right now, it seems to add the values in javascript to the list, instead of changing them. It only needs to change the original text value.

I think I'm pretty close but I get some odd results (this doesn't happen when I do it without childnodes). It's probably something minor, but I still appreciate anyone giving it a look!

javascript

addEventListener("load",init,false);

function init(){
    let span = document.getElementsByClassName("aantal");
    span[0].innerHTML = "3";

    let node = document.getElementsByClassName("list")[0].parentNode;
    node.firstChild.nodeValue = "ROOD";
    node.childNodes[1].nodeValue = "GROEN";
    node.childNodes[2].nodeValue = "BLAUW";

}

html

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8"/>
    <title>Slides Opdracht04</title>
    <link href="style/stijl.css" rel="stylesheet" />
    <script src="js/demo4.js"></script>
</head>
<body>
    <p>Kleuren</p>
    <ul>
        <li class="list">Rood</li>
        <li class="list">Groen</li>
        <li class="list">Blauw</li>
    </ul>
    <p>De lijst bevat <span class="aantal"></span> kleuren</p>
</body>
</html>
FluffyKitten
  • 13,824
  • 10
  • 39
  • 52

2 Answers2

2

Use the toUpperCase() function on the nodeValue

let node = document.getElementsByClassName("list")[0].parentNode;
let numChildNodes = node.childNodes.length;
for (var i = 0; i < numChildNodes; i++) {
    node.childNodes[i].nodeValue = node.childNodes[i].nodeValue.toUpperCase();
}
Dan Mullin
  • 4,285
  • 2
  • 18
  • 34
  • that's great, it's works! the school does want us to type it out though(prolly to give insight), but I appreciate nonetheless – lil benchpress Aug 18 '20 at 15:15
2

Let's examine those childNodes more closely.

const childNodes = document.querySelector('#parent').childNodes

console.log('Total', childNodes.length)
console.log([...childNodes]
  .map(({ nodeType, textContent, nodeValue }) => ({ nodeType, textContent, nodeValue })))
<ul id="parent">
    <li class="list">Rood</li>
    <li class="list">Groen</li>
    <li class="list">Blauw</li>
</ul>

As you can see from the output, #parent has 7 childNodes, not 3 as you might expect. Four are "nodeType: 3", which means they're text nodes. As you can see, they contain only whitespace. The remaining 3 are "nodeType: 1", which means they're HTML elements. These are the li children.

When you set the nodeValues of nodes 0..2, you're actually setting them on the first 2 whitespace text nodes plus one of the lis. Setting the nodeValue of an HTML element is a no-op, so that one is ignored. Thus, you get:

[0] WHITESPACE     => "ROOD"
[1] <li>Rood</li>  => "GROEN" # no-op - nothing happens
[2] WHITESPACE     => "BLAUW"
# other elements at indexes > 2 - out of scope, nothing happens
Lionel Rowe
  • 5,164
  • 1
  • 14
  • 27
  • 1
    @lilbenchpress It's quite rare you'll need to do something like setting an individual `nodeValue` - this is a really surgical and precise way of manipulating the DOM. But it's also great to learn about these details if you want to deeply understand what's going on in the browser! – Lionel Rowe Aug 18 '20 at 16:34
  • It's a bit of an odd school exercise, but you've definitely given me some insight in the matter! All the rest of the requirements went fine, so we should be good! Thanks again, you're a lifesaver – lil benchpress Aug 18 '20 at 17:16