for循环操作element.ClassList仅获首个元素类,其余为undefined的问题
Hey there! Let's break down why you're only getting the first element's class name and others return undefined, then fix up your code to work as expected.
The Core Problem
Your mistake comes from mixing up two completely different indices:
- The
iin your loop refers to the position of the button in theallbucollection (e.g., 0 for the first button, 1 for the second, etc.) - When you use
allbu[i].classList[i], you're trying to access the i-th class of the i-th button. But most of your buttons only have one class! So for the second button (i=1),classList[1]doesn't exist (its only class is at index 0), hence theundefined.
Step 1: Fix the buttoncopy Array
If you want to store the original class of each button (for resetting later), you should grab the first (and only) class of each button. Here's how to fix that loop:
var allbu = document.getElementsByTagName('button'); var buttoncopy = []; for (let i = 0; i < allbu.length; i++) { // Grab the first (and only) class of each button buttoncopy.push(allbu[i].classList[0]); } console.log(buttoncopy);
Step 2: Fix the Color Switching Functions
Instead of trying to remove allbu[i].classList[i] (which is incorrect), we'll use a cleaner approach: remove all possible color classes before adding the new one. We'll also add a proper reset function since your dropdown has a "Reset" option:
function buchange(btc) { if (btc.value == 'red') { btcred(); } else if (btc.value == 'blue') { btcblue(); } else if (btc.value == 'green') { btcgreen(); } else if (btc.value == 'reset') { resetButtons(); } } // Reusable function to avoid duplicate code function updateButtonColors(newClass) { for (let i = 0; i < allbu.length; i++) { // Remove all possible color classes first allbu[i].classList.remove('redbu', 'bluebu', 'greenbu', 'yellowbu'); allbu[i].classList.add(newClass); } } function btcred() { updateButtonColors('redbu'); } function btcblue() { updateButtonColors('bluebu'); } function btcgreen() { updateButtonColors('greenbu'); } function resetButtons() { for (let i = 0; i < allbu.length; i++) { // Remove current color class, add back the original one allbu[i].classList.remove('redbu', 'bluebu', 'greenbu', 'yellowbu'); allbu[i].classList.add(buttoncopy[i]); } }
Bonus: Clean Up with a Switch Statement
To make your buchange function even cleaner, you can use a switch statement instead of multiple if/else checks:
function buchange(btc) { switch(btc.value) { case 'red': updateButtonColors('redbu'); break; case 'blue': updateButtonColors('bluebu'); break; case 'green': updateButtonColors('greenbu'); break; case 'reset': resetButtons(); break; // Add the random case logic here later if needed! } }
Full Working JavaScript Code
Here's the complete fixed JS:
var allbu = document.getElementsByTagName('button'); var buttoncopy = []; for (let i = 0; i < allbu.length; i++) { buttoncopy.push(allbu[i].classList[0]); } console.log(buttoncopy); function buchange(btc) { switch(btc.value) { case 'red': updateButtonColors('redbu'); break; case 'blue': updateButtonColors('bluebu'); break; case 'green': updateButtonColors('greenbu'); break; case 'reset': resetButtons(); break; } } function updateButtonColors(newClass) { for (let i = 0; i < allbu.length; i++) { allbu[i].classList.remove('redbu', 'bluebu', 'greenbu', 'yellowbu'); allbu[i].classList.add(newClass); } } function resetButtons() { for (let i = 0; i < allbu.length; i++) { allbu[i].classList.remove('redbu', 'bluebu', 'greenbu', 'yellowbu'); allbu[i].classList.add(buttoncopy[i]); } }
Why This Works
- We no longer mix up button collection indices with class list indices
- We safely remove all possible color classes before adding the new one, so there's no leftover styles
- The reset function uses the original classes stored in
buttoncopyto revert each button back to its initial state
Your CSS and HTML don't need any changes—they're good to go!
内容的提问来源于stack exchange,提问作者Naman Vyas

