I\'m performing a small text with JavaScript with the getElementsByClassName()
and I am getting some unwanted results. I would like the script to change each CS
You have already some good solutions.
I think that the best one is the one from Rick Hitchcock.
But a solution that I often use, to be safe when doing things like that, is to travel the collection backwards
var nmax = blockSet.length - 1;
for (var n=nmax; n>=0; n--) {
blockSet[n].className = 'block-selected';
}
That isolates you from changes in the collection
Definition and Usage
The getElementsByClassName() method returns a collection of all elements in the document with the specified class name, as a NodeList object.
The NodeList object represents a collection of nodes. The nodes can be accessed by index numbers. The index starts at 0.
The use of this property is discouraged because of performance implications (due to the live DOMCollection where any changes to the document must be reflected on the returned object immediately) and complexity (the removal of an element from the document will result in immediate changes to the collection).
And by just adding only blockSet[0].className = "block-selected";
and by clicking on the button it colord each div by each click so we need to click 8 times in order to color all the divs and see the live example below
function myFunction() {
var blockSet = document.getElementsByClassName('block-default');
blockSet[0].className = "block-selected";
}
.block-default {
width: 100px;
height: 50px;
background-color: green;
border: 1px solid red;
padding: 10px;
}
.block-selected {
width: 100px;
height: 50px;
background-color: blue;
border: 1px solid white;
padding: 10px;
}
<button onclick="myFunction()">change</button>
<div class="block-default">BLOCK1</div>
<div class="block-default">BLOCK2</div>
<div class="block-default">BLOCK3</div>
<div class="block-default">BLOCK4</div>
<div class="block-default">BLOCK5</div>
<div class="block-default">BLOCK6</div>
<div class="block-default">BLOCK7</div>
<div class="block-default">BLOCK8</div>
And by adding only var blockSet = document.getElementsByClassName('block-default');
alert("Length are: " + blockSet.length + "\nFirst Item is: " + blockSet[0].childNodes[0].nodeValue);
without the rest it will alert
As in the below live example:
function myFunction() {
var blockSet = document.getElementsByClassName('block-default');
/*
blockSet[0].className = "block-selected";
blockSet[1].className = "block-selected";
blockSet[2].className = "block-selected";
blockSet[3].className = "block-selected";
blockSet[4].className = "block-selected";
blockSet[5].className = "block-selected";
blockSet[6].className = "block-selected";
blockSet[7].className = "block-selected";*/
alert("Length are: " + blockSet.length + "\nFirst Item is: " + blockSet[0].childNodes[0].nodeValue);
}
.block-default {
width: 100px;
height: 50px;
background-color: green;
border: 1px solid red;
padding: 10px;
}
.block-selected {
width: 100px;
height: 50px;
background-color: blue;
border: 1px solid white;
padding: 10px;
}
<button onclick="myFunction()">change</button>
<div class="block-default">BLOCK1</div>
<div class="block-default">BLOCK2</div>
<div class="block-default">BLOCK3</div>
<div class="block-default">BLOCK4</div>
<div class="block-default">BLOCK5</div>
<div class="block-default">BLOCK6</div>
<div class="block-default">BLOCK7</div>
<div class="block-default">BLOCK8</div>
Or we can use it use
document.getElementsByClassName
withfor loop
so a close alternative isquerySelectorAll
as Rick Hitchcock answered it.
function myFunction() {
var blockSet = document.querySelectorAll('.block-default');
blockSet[0].className = "block-selected";
blockSet[1].className = "block-selected";
blockSet[2].className = "block-selected";
blockSet[3].className = "block-selected";
blockSet[4].className = "block-selected";
blockSet[5].className = "block-selected";
blockSet[6].className = "block-selected";
blockSet[7].className = "block-selected";
}
.block-default {
width: 100px;
height: 50px;
background-color: green;
border: 1px solid red;
padding: 10px;
}
.block-selected {
width: 100px;
height: 50px;
background-color: blue;
border: 1px solid white;
padding: 10px;
}
<button onclick="myFunction()">change</button>
<div class="block-default">BLOCK1</div>
<div class="block-default">BLOCK2</div>
<div class="block-default">BLOCK3</div>
<div class="block-default">BLOCK4</div>
<div class="block-default">BLOCK5</div>
<div class="block-default">BLOCK6</div>
<div class="block-default">BLOCK7</div>
<div class="block-default">BLOCK8</div>
I hope my post it helps, let me know if you have any question.
This error occurs because blockSet
is an HTMLCollection
, which is "live." HTMLCollections
update as the elements on the page update.
Every time you swap a className
, you're making blockSet
shorter one by one.
To solve this problem, just do this instead:
for (var i = 0; i < 8; i += 1) {
blockSet[ 0 ].className = "block-selected";
}
That way you chunk your HTMLCollection
off one by one.
Iteration 1: [ div1, div2, div3, div4, div5, div6, div7, div8 ]
Iteration 2: [ div2, div3, div4, div5, div6, div7, div8 ]
Iteration 3: [ div3, div4, div5, div6, div7, div8 ]
Iteration 4: [ div4, div5, div6, div7, div8 ]
Iteration 5: [ div5, div6, div7, div8 ]
Iteration 6: [ div6, div7, div8 ]
Iteration 7: [ div7, div8 ]
Iteration 8: [ div8 ]
Hope that helps!