firstChild, lastChild, nextSibling
firstChild,lastChild,nextSibling,previousSibling— свойства интерфейсаNode, возвращающие соседние и дочерние узлы DOM-дерева включая текстовые узлы и комментарии.
Зачем нужно
Эти свойства дают низкоуровневый доступ ко всем узлам дерева, включая текстовые (пробелы, переводы строк). Важно отличать их от firstElementChild, lastElementChild и nextElementSibling, которые возвращают только узлы-элементы (Element) и используются значительно чаще в практической работе.
Где используется
- Обход DOM-дерева для поиска узлов
- Работа с текстовыми узлами напрямую
- Низкоуровневые манипуляции при реализации парсеров/рендереров
- Итерация по соседним элементам
Node vs Element свойства
| Node свойство | Element аналог | Возвращает |
|---|---|---|
firstChild |
firstElementChild |
Node (любой тип) / Element |
lastChild |
lastElementChild |
Node / Element |
nextSibling |
nextElementSibling |
Node / Element |
previousSibling |
previousElementSibling |
Node / Element |
childNodes |
children |
NodeList / HTMLCollection |
Примеры
firstChild vs firstElementChild
// HTML: <ul>\n <li>Первый</li>\n</ul>
const ul = document.querySelector('ul');
console.log(ul.firstChild); // TextNode "\n " (пробел/перенос!)
console.log(ul.firstElementChild); // <li>Первый</li>
console.log(ul.lastChild); // TextNode "\n"
console.log(ul.lastElementChild); // последний <li>
Навигация по соседям
const current = document.querySelector('.active');
// Следующий узел (может быть текстовым)
console.log(current.nextSibling);
// Следующий элемент (пропускает текстовые узлы)
const next = current.nextElementSibling;
const prev = current.previousElementSibling;
if (next) next.classList.add('next');
if (prev) prev.classList.add('prev');
Обход childNodes
const container = document.querySelector('.container');
// childNodes включает текстовые узлы
for (const node of container.childNodes) {
if (node.nodeType === Node.TEXT_NODE) {
console.log('Текст:', node.textContent.trim());
} else if (node.nodeType === Node.ELEMENT_NODE) {
console.log('Элемент:', node.tagName);
}
}
Практический обход: карусель
function nextSlide(current) {
return current.nextElementSibling || current.parentElement.firstElementChild;
}
function prevSlide(current) {
return current.previousElementSibling || current.parentElement.lastElementChild;
}
Частые ошибки
- Ожидание Element от
firstChild— между тегами часто есть пробелы, которые являются текстовыми узлами; используйтеfirstElementChildесли нужен элемент. - Проверка на
null— если у элемента нет соседей/детей, свойства возвращаютnull; без проверки —TypeError. - Изменение
childNodesв цикле —childNodes— живая коллекция; удаление узлов во время итерации сдвигает индексы; переведите в массив:[...el.childNodes].
Связанные темы
- _MOC DOM
- _MOC JavaScript
- parentElement, children, siblings
- closest -- поиск родителя
- createElement и createTextNode