Подтвердить что ты не робот

Цикл через childNodes

Я пытаюсь выполнить цикл через childNodes следующим образом:

var children = element.childNodes;
children.forEach(function(item){
    console.log(item);
});

Однако, он выводит Uncaught TypeError: undefined is not a function из-за функции forEach. Я также пытаюсь использовать children вместо childNodes, но ничего не изменилось.

Кто-нибудь знает, что происходит?

4b9b3361

Ответ 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]
    }