Списки узлов DOM. Динамика в примере.

При поиске элементов в DOM надо помнить одну простую вещь: все списки узлов - не массивы Array, а специальные динамичные сущности DOMNodeList.

Какое это имеет значение? Разберем на примере.

Для этого сделаем функцию, чтобы удаляла все дочерние элементы узла. Она будет получать список узлов и по очереди удалять каждый, вот так:

function removeChildren(node) {
    var children = node.childNodes

    for(var i=0;i<children.length; i++) {
        var child = children[i]
        
        node.removeChild(child)
    }
}

Проверим работу функции на тестовом списке.

  1. Саша
  2. Маша
  3. Паша
  4. Даша

С одного нажатия все узлы удалить не получится. Проверьте. Почему?

Причина в том, что childNodes всегда содержит упорядоченный список текущих детей.

При работе функции removeChildren сначала удаляется первый элемент списка, children[0] (Саша). Если посмотреть на children после удаления, то обнаружится интересная картина:

Было:

  1. [0] Саша
  2. [1] Маша
  3. [2] Паша
  4. [3] Даша

Сашу удалили. Стало:

  1. [0] Маша
  2. [1] Паша
  3. [2] Даша

Список DOM-узлов по-прежнему начинается с 0, а функция продолжает удалять с children[1], так что Маша остается на месте:

  1. [0] Маша
  2. [1] Даша

Свойство length, как и сам список, отражает текущую картину вещей, поэтму цикл не идет дальше i=2 и заканчивает свою работу, удалив ровно половину элементов.

Как сделать правильно работающую функцию?

Вот один из вариантов:

function removeChildren(node) {
    var children = node.childNodes

    while(children.length) {
        node.removeChild(children[0])
    }
}

Общий принцип такой: если вам нужно производить изменения с набором DOM-узлов - имейте в виду, что все ваши изменения отражаются в DOM не после окончания работы скрипта, а сразу же.