Цикл for обходит не всю коллекцию
Есть таблица, которая генерируется следующим образом:
let table = document.createElement("table");
table.setAttribute('border','1');
for (let i = 0; i < 5; i++) {
let newRow = table.insertRow(0);
for (let j = 0; j < 5; j++) {
let newCell = newRow.insertCell(0);
newCell.className = "white_cell";
}
}
document.getElementById("for_table").appendChild(table)
Есть кнопка, которая должна менять цвет ячеек с белого на чёрный с помощью такой функции
function change_color() {
let arrCell_w = document.getElementsByClassName("white_cell");
console.log(arrCell_w.length);
console.log(arrCell_w);
for (let i = 0; i < arrCell_w.length; i++) {
//console.log(i)
//console.log(arrCell_w[i]);
arrCell_w[i].className = "black_cell";
}
}
Судя по логам, находятся всё, что нужно, но цвет меняется только у половины ячеек. Подскажите, пожалуйста, в чём может быть ошибка?
Ответы (1 шт):
getElementsByClassName возвращает "живую" HTMLCollection коллекцию элементов.
На первой итерации мы получаем первый элемент по индексу [0] и изменяем его класс cell.black_cell. В этот момент коллекция table.cell.white_cell обновляется и первый элемент из нее выпадает. На второй итерации мы обращаемся к индексу [1], но в обновленной коллекции, второй элемент таблицы сместился в индекс [0]. Таким образом, мы пропустили второй элемент и реально получили третий. По итогу раскрасится все через один элемент.
| index table | 1 итерация / index cell | 2 итерация / index cell |
|---|---|---|
| 0 | c_white [0] <- мы тут | c_black |
| 1 | c_white [1] | c_white [0] <- пропустили |
| 2 | c_white [2] | c_white [1] <- мы тут |
Просто превратим эту коллекцию в "неживой" массив.
let table = document.createElement("table")
table.setAttribute('border', '1')
for (let i = 0; i < 5; i++) {
let newRow = table.insertRow(0)
for (let j = 0; j < 5; j++) {
let newCell = newRow.insertCell(0)
newCell.className = "white_cell"
newCell.textContent = "Cell"
}
}
document.body.appendChild(table)
function change_color() {
let arrCell_w = [...document.getElementsByClassName("white_cell")]
for (let i = 0; i < arrCell_w.length; i++) {
arrCell_w[i].className = "black_cell"
}
}
document.querySelector("button").addEventListener("click", change_color)
.white_cell {
background-color: white;
}
.black_cell {
background-color: darkgray;
}
<button start>Start</button>