Подтвердить что ты не робот

Странное поведение при переборе HTMLCollection из getElementsByClassName

Я написал функцию для изменения класса элементов, чтобы изменить их свойства. По какой-то причине изменились только некоторые элементы. Мне понадобилось несколько часов, чтобы найти решение, но мне это показалось странным. Возможно, вы можете объяснить это мне.

Это не работает:

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

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

См. JSFiddle: затрагивается только каждый второй элемент; только каждый второй красный элемент меняет цвет на синий.

Поэтому я изменил окончательное выражение цикла for, чтобы больше не увеличивать i:

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

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

Это хорошо работает! Похоже, что вызывается push и никакого увеличения не требуется. Это нормально? Это отличается от примеров, которые я видел.

4b9b3361

Ответ 1

Что происходит, это странный побочный эффект. Когда вы переназначаете className для каждого элемента elements, элемент удаляется из массива! (На самом деле, как указывает @user2428118, elements - объект, подобный массиву, а не массив. См. этот поток для разницы.) Это потому, что он не более длинное имя класса classOne. Когда ваш цикл выходит (во втором случае), массив elements будет пустым.

Вы можете написать свой цикл как:

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

В вашем первом случае, увеличивая i, вы пропускаете половину (оригинальных) элементов с классом classOne.

Отличный вопрос, кстати. Хорошо изучены и понятны.

Ответ 2

getElementsByClassName возвращает NodeList. Коллекция NodeList - это живая коллекция, что означает, что изменение документа влияет на коллекцию. более

Ответ 3

Или верните цикл, начиная с длины-1 и опустившись до 0