web-dev-qa-db-ja.com

childNodesをループする

私はこのようなchildNodesをループしようとしています:

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

ただし、forEach関数によりUncaught TypeError: undefined is not a functionを出力します。また、childrenの代わりにchildNodesを使用しようとしましたが、何も変わりませんでした。

誰が何が起こっているか知っていますか?

63
user3828771

変数childrenNodeList インスタンスであり、NodeListsはtrueではありません Array であるため、 forEach メソッドを継承しません。

また、一部のブラウザは実際にサポートしています nodeList.forEach


ES5

sliceArray を使用して、NodeListを適切なArrayに変換できます。

var array = Array.prototype.slice.call(children);

また、単に call を使用してforEachを呼び出し、NodeListをコンテキストとして渡すこともできます。

[].forEach.call(children, function(child) {});


ES6

from メソッドを使用して、NodeListArrayに変換できます。

var array = Array.from(children);

または、 スプレッド構文... を使用することもできます

let array = [ ...children ];


使用できるハックはNodeList.prototype.forEach = Array.prototype.forEachであり、毎回変換することなくforEachNodeListとともに使用できます。

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

NodeLists、Arrays、NodeListsの変換、DOMの理解についての包括的な説明 を参照して、適切な説明とその他の方法を確認してください。

97
GillesC

私はパーティーに非常に遅れていますが、element.lastChild.nextSibling === null以来、以下は私にとって最も簡単なオプションのようです。

for(var child=element.firstChild; child!==null; child=child.nextSibling) {
    console.log(child);
}
21
Emmet

for-inループでこれを行う方法を次に示します。

var children = element.childNodes;

for(child in children){
    console.log(children[child]);
}
15
AdityaParab

forループで試してください。ノードのコレクションforEachであるため、nodelistでエラーが発生します。

または、ノードリストを配列に変換する必要があります

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);
3
Mritunjay
const results = Array.from(myNodeList.values()).map(parser_item);

NodeListは配列ではありません しかしNodeList.values()は配列反復子を返すため、配列に変換できます。

2
Xu Qinghan

NodeListを反復処理するES6の機能的な方法を次に示します。このメソッドは、次のようにArrayforEachを使用します。

Array.prototype.forEach.call(element.childNodes, f)

ここで、fは、子ノードを最初のパラメーターとして受け取り、インデックスを2番目として受け取る反復関数です。

NodeListを複数回繰り返す必要がある場合は、これから小さな機能的なユーティリティメソッドを作成できます。

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()および他の配列関数に対して同じトリックを行うことができます。)

1
F Lekschas

これを試してください[逆順走査]:

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);
1
user2575725

childElementCountを使用して、別のメソッドを追加することに抵抗できませんでした。指定された親からの子要素ノードの数を返すので、ループすることができます。

for(var i=0, len = parent.childElementCount ; i < len; ++i){
    ... do something with parent.children[i]
    }
0
Michel

この種のことをたくさんやるなら、関数を自分で定義する価値があるかもしれません。

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 );
        }
    };
}
0
P Hemans