If you go to
http://stevenh.fatcow.com/test/index.html
click on the top-right box (GPS TIMING) and look at the console,
I dont see why the looping through the array only happens 9 tomes, the array holds 20
If you go to
http://stevenh.fatcow.com/test/index.html
click on the top-right box (GPS TIMING) and look at the console,
That can happen when you remove items from what you are looping through.
Let’s take a look at what’s happening:
var cables = document.getElementsByClassName("cable");
console.log(cables);
console.log(cables.length);
for (i = 0; i < cables.length; i++) {
cables[i].classList.remove( 'cable' );
console.log(i);
cables[i].classList.add( 'inactive-cable' );
}
The getElementsByClassName documentation page says: elements is a live HTMLCollection of found elements.
So when you remove a class name, the cables collection also updates. That’s not good when you’re using a for loop. You can fix that problem by looping backwards through the collection instead.
A better solution is to use querySelectorAll instead, which gives you a non-live nodelist instead.
// var cables = document.getElementsByClassName("cable");
var cables = document.querySelectorAll(".cable");
You can also use the replace method, to replace an old class with a new class.
// cables[i].classList.remove( 'cable' );
// cables[i].classList.add( 'inactive-cable' );
cables[i].classList.replace( 'cable', 'inactive-cable' );
querySelectorAll also has a forEach method, letting you easily loop through each of the items.
var cables = document.querySelectorAll(".cable");
// for (i = 0; i < cables.length; i++) {
cables.forEach(function (cable) {
// cables[i].classList.replace( 'cable', 'inactive-cable' ));
cable.classList.replace( 'cable', 'inactive-cable' ));
});
And now that the loop statement is simple enough, you could even use arrow notation there instead.
var cables = document.querySelectorAll(".cable");
cables.forEach(
(cable) => cable.classList.replace( 'cable', 'inactive-cable' )
);
And if you don’t need the cables variable for anything else, you could condense that to:
document.querySelectorAll(".cable").forEach(
(cable) => cable.classList.replace( 'cable', 'inactive-cable' )
);
Another Grace Hopper Building question. I once was in Grace Hopper’s office in the Pentagon; I should visit the Grace Hopper Building next time I am in San Diego.
Try using try/catch around the code. I think what is happening is that there is an error causing the loop to be terminated prematurely. I don’t see items being added to or removed from the cables array so I think that is not the cause.
Do you know how to use breakpoints in the debugger and single-step through the debugger? You could break at the beginning of the loop then single-step until you get to the item where the loop ends and try to see a problem there.
So I would log more data. I would at least log cables[i].classList
at the beginning of the loop to see what it is before the remove and add. Other things like i
and cables.length
at the top might help. Yes i
does not change during the loop but it helps to have it so it is easier to match with the other data.
Because cables is a live collection, thanks to getElementsByTagName, every time you change the document that collection is updated too. That results in a shorter cables array length each time you remove one of the cable class names.
All of the code examples in my previous post fix that problem. I recommend the last example I gave.
This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.