私はこのようなchildNodesをループしようとしています:
var children = element.childNodes;
children.forEach(function(item){
console.log(item);
});
ただし、forEach
関数によりUncaught TypeError: undefined is not a function
を出力します。また、children
の代わりにchildNodes
を使用しようとしましたが、何も変わりませんでした。
誰が何が起こっているか知っていますか?
変数children
は NodeList
インスタンスであり、NodeList
sは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 ];
使用できるハックは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、Arrays、NodeListsの変換、DOMの理解についての包括的な説明 を参照して、適切な説明とその他の方法を確認してください。
私はパーティーに非常に遅れていますが、element.lastChild.nextSibling === null
以来、以下は私にとって最も簡単なオプションのようです。
for(var child=element.firstChild; child!==null; child=child.nextSibling) {
console.log(child);
}
for-in
ループでこれを行う方法を次に示します。
var children = element.childNodes;
for(child in children){
console.log(children[child]);
}
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);
const results = Array.from(myNodeList.values()).map(parser_item);
NodeListは配列ではありません しかしNodeList.values()は配列反復子を返すため、配列に変換できます。
NodeList
を反復処理するES6の機能的な方法を次に示します。このメソッドは、次のようにArray
のforEach
を使用します。
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()
および他の配列関数に対して同じトリックを行うことができます。)
これを試してください[逆順走査]:
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);
childElementCount
を使用して、別のメソッドを追加することに抵抗できませんでした。指定された親からの子要素ノードの数を返すので、ループすることができます。
for(var i=0, len = parent.childElementCount ; i < len; ++i){
... do something with parent.children[i]
}
この種のことをたくさんやるなら、関数を自分で定義する価値があるかもしれません。
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 );
}
};
}