Comportamiento extraño al iterar sobre HTMLCollection desde getElementsByClassName

Resuelto MeNa asked hace 11 años • 3 respuestas

Escribí una función para cambiar la clase de elementos para cambiar sus propiedades. Por alguna razón, sólo algunos de los elementos han cambiado. Me tomó algunas horas encontrar una solución, pero me parece extraño. Quizás puedas explicarme esto.

Esto no funciona:

function replace(){
  var elements = document.getElementsByClassName('classOne');

  for (var i = 0; i < elements.length; i++) {
    elements[i].className = 'classTwo';               
  }
}

Consulte JSFiddle : solo uno de cada dos elementos se ve afectado; sólo uno de cada dos elementos rojos cambia de color a azul.

Así que cambié la expresión final del forbucle para que no se incremente imás:

function replace(){
  var elements = document.getElementsByClassName('classOne');

  for (var i = 0; i < elements.length; i) { // Here’s the difference
    elements[i].className = 'classTwo';               
  }
}

¡Esto funciona bien! Parece que pushse llama y no se necesita ningún incremento. ¿Esto es normal? Es diferente de los ejemplos que he visto.

MeNa avatar Mar 22 '13 10:03 MeNa
Aceptado

Lo que está pasando es un extraño efecto secundario. Cuando reasignas classNamecada elemento de elements, ¡el elemento se elimina de la matriz! (En realidad, como señala @user2428118, elementses un objeto similar a una matriz , no una matriz. Consulte este hilo para conocer la diferencia). Esto se debe a que ya no tiene el classOnenombre de clase. Cuando su ciclo salga (en el segundo caso), la elementsmatriz estará vacía.

Podrías escribir tu bucle como:

while (elements.length) {
    elements[0].className = 'classTwo'; // removes elements[0] from elements!
}

En el primer caso, al incrementar i, estás omitiendo la mitad de los elementos (originales) que tienen class classOne.

Excelente pregunta, por cierto. Bien investigado y claro.

Ted Hopp avatar Mar 22 '2013 04:03 Ted Hopp

getElementsByClassNamedevuelve una lista de nodos. Una colección NodeList es una colección viva, lo que significa que la modificación del documento afecta a la colección. más

NoodleFolk avatar Mar 22 '2013 06:03 NoodleFolk