nodeValue returns null (deep understanding)

2k Views Asked by At

The idea was to console log node value. But instead of names it returns null. I don't see why, because code seems fine to me. So, I want understand what happening. I found how to make it work, but I don't understand why my code don't work. Code and results:

HTML

 <div>Users:</div>
  <ul id="myList">
    <li>John</li>
    <li>Doe</li>
  </ul> 

JavaScript

let listNode = document.body.children[1].children[1]

console.log(listNode)

// Why not return node value?
let value = listNode.nodeValue
console.log(value)

Results: link

2

There are 2 best solutions below

0
Scott Marcus On BEST ANSWER

When representing HTML elements (DOM Objects) in JavaScript, everything is a node - - even the text within an element. But, not all nodes are elements. So when you got a reference to an <li>, that <li> wasn't the node that contained the name, it was the child text node of that <li>. Another way to say this is that element nodes don't ever have a value of their own, their children do and that is why you were getting null when you tried to get the nodeValue of an <li>

To get that content, you must navigate all the way down to that node:

// Get a node list of all the <li> child elements in the #myList list:
let listNodes = document.querySelectorAll("#myList > li");

// Go to the first <li> in the node list and then navigate the the text node contained within that node
let value = listNodes[0].firstChild.nodeValue;
console.log("The <li>.firstChild node value is: " + value);
console.log("The <li> node type is: " + listNodes[0].nodeType + " (1 = element node)");
console.log("The <li>.firstChild node type is: " + listNodes[0].firstChild.nodeType + " (3 = text node)");
<div>Users:</div>
 <ul id="myList">
    <li>John</li>
    <li>Doe</li>
 </ul>

But, the DOM also exposes other ways to go straight to the content within an element via .textContent and .innerHTML:

// Get a node list of all the <li> child elements in the #myList list:
let listNodes = document.querySelectorAll("#myList > li");

// .textContent allows you to extract the text of an element without navigating 
// into its text node
let value = listNodes[1].textContent;
console.log(value);

// While .innerHTML allows you to acces the HTML within an element:
value = listNodes[1].innerHTML;
console.log(value);
<div>Users:</div>
 <ul id="myList">
    <li>John</li>
    <li><a href="">Doe</a></li>
 </ul>

0
Mohamed Abbas On

Because Done in your li is a node, texts is nodes also not only HTML tags

Your code after update:

let listNode = document.body.children[1].children[1]

console.log(listNode)

// Why not return node value?
let value = listNode.childNodes[0].nodeValue;
console.log(value)
<div>Users:</div>
  <ul id="myList">
    <li>John</li>
    <li>Doe</li>
  </ul>