Reputation: 2231
Scenario
I would like to get all child nodes of my div and change it color. Code:
function myFunction() {
var divv = document.getElementById("divv");
var myCollection = divv.childNodes;
var len = myCollection.length;
var i;
for (i = 0; i < len; i++) {
myCollection[i].style.color = "red";
}
}
<div id="divv">
<h2>JavaScript HTML DOM</h2>
<p>Hello World!</p>
<p>Hello Norway!</p>
<p>Click the button to change the color of all p elements.</p>
<button onclick="myFunction()">Try it</button>
</div>
Error: This is not working. It seems tha in my collection i have all nodes. h2 p text buton. I Expeceted just p h2 and buton.
EDIT Explanation Note: Whitespace inside elements is considered as text, and text is considered as nodes. Comments are also considered as nodes.
So we need to check if node is element node, or use querySelectorAll. Examples in answers below. Thanks for your help.
Upvotes: 0
Views: 381
Reputation: 40648
You could use the children
property to access the children of a given node:
The
ParentNode
propertychildren
is a read-only property that returns a live HTMLCollection which contains all of the child elements of the node upon which it was called.
function myFunction() {
var divv = document.getElementById("divv");
var myCollection = divv.children;
var len = myCollection.length;
var i;
for (i = 0; i < len; i++) {
myCollection[i].style.color = "red";
}
}
<div id="divv">
<h2>JavaScript HTML DOM</h2>
<p>Hello World!</p>
<p>Hello Norway!</p>
<p>Click the button to change the color of all p elements.</p>
<button onclick="myFunction()">Try it</button>
</div>
Another way to do with ES6 would be to spread the child nodes into an array and loop through them with a .forEach
:
const myFunction = () => {
[...document.querySelector('#divv').children].forEach(child => {
child.style.color = 'red';
});
}
<div id="divv">
<div class="child">
I am a child
</div>
<div>
<div class="grandchild">
I am a grand child
</div>
</div>
<button onclick="myFunction()">Try it</button>
</div>
Alternatively, you could use the .forEach
from the NodeList
class directly but the previous method gives you more freedom to work with Array's method such as .reduce
, .map
, etc...
const myFunction = () => {
document.querySelectorAll('#divv > *').forEach(child => {
child.style.color = 'red';
});
}
<div id="divv">
<div class="child">
I am a child
</div>
<div>
<div class="grandchild">
I am a grand child
</div>
</div>
<button onclick="myFunction()">Try it</button>
</div>
Upvotes: 3
Reputation: 370729
Text nodes do not have style
attributes. If you want to use childNodes
, check that the nodeType
is 1 (an Element
node) first:
function myFunction() {
var divv = document.getElementById("divv");
var myCollection = divv.childNodes;
var len = myCollection.length;
var i;
for (i = 0; i < len; i++) {
if (myCollection[i].nodeType === 1) myCollection[i].style.color = "red";
}
}
<div id="divv">
<h2>JavaScript HTML DOM</h2>
<p>Hello World!</p>
<p>Hello Norway!</p>
<p>Click the button to change the color of all p elements.</p>
<button onclick="myFunction()">Try it</button>
</div>
But I would prefer using querySelectorAll
and forEach
here:
function myFunction() {
document.querySelectorAll('#divv > *')
.forEach(child => child.style.color = "red");
}
<div id="divv">
<h2>JavaScript HTML DOM</h2>
<p>Hello World!</p>
<p>Hello Norway!</p>
<p>Click the button to change the color of all p elements.</p>
<button onclick="myFunction()">Try it</button>
</div>
(or, you could simply set #divv
's style.color
to red)
Upvotes: 4