Tengo problemas con este script a continuación, ya que tomo una colección basada en un nombre de clase y luego modifico los nombres de clase de cada miembro de la colección, respectivamente, los programas desencadenan que los mismos elementos de la colección no están definidos.
Supongo que esto tiene que ver con el desmoronamiento de la colección cuando elimino lo que hizo que los elementos pertenezcan a la colección. ¿Podría darme una pista sobre cómo podría implementar algo como esto?
<script> var toggle1 = document.getElementById("toggle1"); toggle1.addEventListener("click", Colortoggle); function Colortoggle() { if (toggle1.className === " white") { var collection = document.getElementsByClassName("white"); for (let i = 0; i < collection.length; i++) { collection[i].className -= "white"; collection[i].className += "black"; } } else { var collection = document.getElementsByClassName("black"); for (let i = 0; i < collection.length; i++) { collection[i].className -= "black"; collection[i].className += "white"; } } console.log("colortoggle was finished"); } </script>La lógica principal para el código a continuación es toggle1.classList.contains("white") Esta declaración devuelve verdadero si alternar tiene clase white ; de lo contrario, devuelve falso.
Con elementos DOM puede usar estos métodos classList classList.add() , classList.remove() .
classList.add() => esto agregará clase al elemento DOM seleccionado.
classList.remove() => esto eliminará la clase del elemento DOM seleccionado.
para obtener más información sobre el método abslout classList, visite este.
var toggle1 = document.querySelector("#toggle1"); toggle1.addEventListener("click", Colortoggle); function Colortoggle() { if (toggle1.classList.contains("white")) { var collection = document.querySelectorAll(".white"); collection.forEach(element => { element.classList.add("black"); element.classList.remove("white"); }) } else { var collection = document.querySelectorAll(".black"); collection.forEach(element => { element.classList.add("white"); element.classList.remove("black"); }) } console.log("colortoggle was finished"); } .main div { display: inline-block; height: 100px; width: 100px; } .white { background-color: #f0f0f0; color: black; } .black { background-color: #000000; color: white; } <div class="main"> <div id="toggle1" class="white">toggle1 click here</div> <div class="white"></div> <div class="white"></div> <div class="black"></div> <div class="black"></div> </div>Como nota al margen: getElementsByClassName() devuelve una HTMLCollection en vivo , lo que significa que nunca debe iterar sobre ella usando un bucle for mientras modifica elementos como que se eliminan de la colección .
Vamos a imaginar esto:
Sea esta la colección getElementsByClassName('foo') , con -> mostrando la iteración actual del ciclo.
// list before iterating 0: <div class="foo">0</div> 1: <div class="foo">1</div> 2: <div class="foo">2</div> // first iteration i=0 -> 0: <div class="foo">0</div> // in this iteration, remove .foo 1: <div class="foo">1</div> 2: <div class="foo">2</div> // still first iteration, but now collection[0] is actually what was collection[1] before -> 0: <div class="foo">1</div> 1: <div class="foo">2</div> // second iteration i=1 0: <div class="foo">1</div> // we never touch this one!! -> 1: <div class="foo">2</div> No tendrá este problema si en lugar de getElementsByClassName('foo') trabaja con querySelectorAll('.foo') .
Segunda nota al margen: No, esto no se puede arreglar usando for (const div of divs) en su lugar, ya que internamente parece funcionar también con índices.