Цикл через childNodes
Я пытаюсь выполнить цикл через childNodes следующим образом:
var children = element.childNodes;
children.forEach(function(item){
console.log(item);
});
Однако, он выводит Uncaught TypeError: undefined is not a function
из-за функции forEach
. Я также пытаюсь использовать children
вместо childNodes
, но ничего не изменилось.
Кто-нибудь знает, что происходит?
Ответы
Ответ 1
Переменная children
- это NodeList
экземпляр и NodeList
не соответствуют true Array
, и поэтому они не наследуют метод forEach
.
Также некоторые браузеры действительно поддерживают его nodeList.forEach
ES5
Вы можете использовать slice
из Array
, чтобы преобразовать NodeList
в правильный Array
.
var array = Array.prototype.slice.call(children);
Вы также можете просто использовать call
для вызова forEach
и передать его как NodeList
как контекст.
[].forEach.call(children, function(child) {});
ES6
Вы можете использовать метод from
для преобразования вашего NodeList
в Array
.
var array = Array.from(children);
Или вы также можете использовать синтаксис распространения ...
так
let array = [ ...children ];
Используемый hack файл NodeList.prototype.forEach = Array.prototype.forEach
, и вы можете использовать forEach
с любым NodeList
без необходимости их конвертировать каждый раз.
NodeList.prototype.forEach = Array.prototype.forEach
var children = element.childNodes;
children.forEach(function(item){
console.log(item);
});
См. Полное погружение в NodeLists, массивы, преобразование NodeLists и понимание DOM для хорошего объяснения и других способов сделать это.
Ответ 2
Я очень опаздываю на вечеринку, но с element.lastChild.nextSibling === null
следующее выглядит как самый простой вариант для меня:
for(var child=element.firstChild; child!==null; child=child.nextSibling) {
console.log(child);
}
Ответ 3
Вот как вы можете это сделать с помощью цикла for-in
.
var children = element.childNodes;
for(child in children){
console.log(children[child]);
}
Ответ 4
Попробуйте выполнить цикл for
. Он дает ошибку в forEach
, потому что это набор узлов nodelist
.
Или это должно преобразовать node -list в массив
function toArray(obj) {
var array = [];
for (var i = 0; i < obj.length; i++) {
array[i] = obj[i];
}
return array;
}
Или вы можете использовать этот
var array = Array.prototype.slice.call(obj);
Ответ 5
const results = Array.from(myNodeList.values()).map(parser_item);
NodeList не является массивом, но NodeList.values() возвращает итератор массива, поэтому может преобразовать его в массив.
Ответ 6
Попробуйте [обход обратного порядка]:
var childs = document.getElementById('parent').childNodes;
var len = childs.length;
if(len --) do {
console.log('node: ', childs[len]);
} while(len --);
ИЛИ [для обхода]
var childs = document.getElementById('parent').childNodes;
var len = childs.length, i = -1;
if(++i < len) do {
console.log('node: ', childs[i]);
} while(++i < len);
Ответ 7
Вот функциональный способ ES6 итерации по NodeList
. Этот метод использует Array
forEach
следующим образом:
Array.prototype.forEach.call(element.childNodes, f)
Где f
- функция итератора, которая получает дочерние узлы в качестве первого параметра и индекс в качестве второго.
Если вам нужно перебирать NodeLists более одного раза, вы можете создать небольшой функциональный служебный метод из этого:
const forEach = f => x => Array.prototype.forEach.call(x, f);
// For example, to log all child nodes
forEach((item) => { console.log(item); })(element.childNodes)
// The functional forEach is handy as you can easily created curried functions
const logChildren = forEach((childNode) => { console.log(childNode); })
logChildren(elementA.childNodes)
logChildren(elementB.childNodes)
(Вы можете сделать тот же трюк для map()
и других функций Array.)
Ответ 8
Если вы так много делаете, то, возможно, стоит определить функцию для себя.
if (typeof NodeList.prototype.forEach == "undefined"){
NodeList.prototype.forEach = function (cb){
for (var i=0; i < this.length; i++) {
var node = this[i];
cb( node, i );
}
};
}
Ответ 9
Не смог удержаться, чтобы добавить другой метод, используя childElementCount
. Он возвращает количество узлов дочерних элементов от данного родителя, поэтому вы можете зацикливаться на нем.
for(var i=0, len = parent.childElementCount ; i < len; ++i){
... do something with parent.children[i]
}