Сценарий
Я хотел бы получить все дочерние узлы моего div и изменить их цвет. Код:
function myFunction() {
var divv = document.getElementById("divv");
var myCollection = divv.childNodes;
var len = myCollection.length;
var i;
for (i = 0; i < len; i++) {
myCollection[i].style.color = "red";
}
}<div id = "divv">
<h2>JavaScript HTML DOM</h2>
<p>Hello World!</p>
<p>Hello Norway!</p>
<p>Click the button to change the color of all p elements.</p>
<button onclick = "myFunction()">Try it</button>
</div>Ошибка: Это не работает. Кажется, что в моей коллекции есть все узлы. h2 p текстовая кнопка. Чувствую только p h2 и buton.
РЕДАКТИРОВАТЬОбъяснение Примечание. Пробелы внутри элементов считаются текстом, а текст - узлами. Комментарии также считаются узлами.
Поэтому нам нужно проверить, является ли node узлом элемента, или использовать querySelectorAll. Примеры в ответах ниже. Спасибо за вашу помощь.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Вы можете использовать свойство children для доступа к дочерним элементам данного узла:
The
ParentNodepropertychildrenis a read-only property that returns a live HTMLCollection which contains all of the child elements of the node upon which it was called.
function myFunction() {
var divv = document.getElementById("divv");
var myCollection = divv.children;
var len = myCollection.length;
var i;
for (i = 0; i < len; i++) {
myCollection[i].style.color = "red";
}
}<div id = "divv">
<h2>JavaScript HTML DOM</h2>
<p>Hello World!</p>
<p>Hello Norway!</p>
<p>Click the button to change the color of all p elements.</p>
<button onclick = "myFunction()">Try it</button>
</div>Другой способ сделать с ES6 - распределить дочерние узлы в массив и перебрать их с помощью .forEach:
const myFunction = () => {
[...document.querySelector('#divv').children].forEach(child => {
child.style.color = 'red';
});
}<div id = "divv">
<div class = "child">
I am a child
</div>
<div>
<div class = "grandchild">
I am a grand child
</div>
</div>
<button onclick = "myFunction()">Try it</button>
</div>В качестве альтернативы вы можете использовать .forEach из класса NodeList напрямую, но предыдущий метод дает вам больше свободы для работы с методом Array, таким как .reduce, .map и т. д.
const myFunction = () => {
document.querySelectorAll('#divv > *').forEach(child => {
child.style.color = 'red';
});
}<div id = "divv">
<div class = "child">
I am a child
</div>
<div>
<div class = "grandchild">
I am a grand child
</div>
</div>
<button onclick = "myFunction()">Try it</button>
</div>ChildNode всегда возвращает и внуков?
@ zolty13, нет The Node.childNodes read-only property returns a live NodeList of child nodes of the given element where the first child node is assigned index 0., поэтому возвращает только детей, а не внуков. Но помните, что, добавляя стиль к родительскому элементу, вы также добавляете стиль детям и внукам!
Итак, почему я получаю 11 элементов из childNode. @CertainPerfomance использует: if (myCollection [i] .nodeType === 1) myCollection [i] .style.color = "red";
Да, вы получаете 11, посмотрите на myCollection, есть только дочерние узлы, а не внуки
@ zolty13, чтобы отличить text от element: прочтите это
Я ожидаю h2 p p p и бутон
Я получил объяснение: Примечание. Пробелы внутри элементов считаются текстом, а текст - узлами. Комментарии также считаются узлами. Спасибо за помощь
Текстовые узлы не имеют атрибутов style. Если вы хотите использовать childNodes, сначала убедитесь, что nodeType равен 1 (узел Element):
function myFunction() {
var divv = document.getElementById("divv");
var myCollection = divv.childNodes;
var len = myCollection.length;
var i;
for (i = 0; i < len; i++) {
if (myCollection[i].nodeType === 1) myCollection[i].style.color = "red";
}
}<div id = "divv">
<h2>JavaScript HTML DOM</h2>
<p>Hello World!</p>
<p>Hello Norway!</p>
<p>Click the button to change the color of all p elements.</p>
<button onclick = "myFunction()">Try it</button>
</div>Но я бы предпочел использовать здесь querySelectorAll и forEach:
function myFunction() {
document.querySelectorAll('#divv > *')
.forEach(child => child.style.color = "red");
}<div id = "divv">
<h2>JavaScript HTML DOM</h2>
<p>Hello World!</p>
<p>Hello Norway!</p>
<p>Click the button to change the color of all p elements.</p>
<button onclick = "myFunction()">Try it</button>
</div>(или вы можете просто установить #divvstyle.color на красный)
Спасибо. Дело не только в цвете :). Это простой пример моей проблемы. Я не понимаю, почему я получаю текстовые узлы, когда мне нужен только дочерний узел. Текстовый узел - внук. var myCollection = divv.childNodes;
Потому что childNodes будет включать текстовые узлы. Новые строки также являются текстовыми узлами. Если вам не нужны текстовые узлы, у вас может быть HTML, например <h2>JavaScript HTML DOM</h2><p>Hello World!</p><p>Hello Norway!</p>, без новой строки и без пробелов между элементами <>s.
Возможный дубликат Использование querySelectorAll для получения прямых потомков