2012-06-30 5 views
5

私はこのコードを作った:私はchilds.lengthが更新されるように、第5、第6行目の間childs=foo.getElementsByTagName("*");を記述する必要はありませんhttp://jsfiddle.net/RL54Z/3/getElementsByTagName( "*")は常に更新されますか?

var foo=document.createElement("div"); 

var childs=foo.getElementsByTagName("*"); 

console.log(childs.length);//0 OK 

var a=document.createElement("a"); 

foo.appendChild(a); 

console.log(childs.length);//1 WTF? 

フィドルを。

どのようにすることができますか?

答えて

3

ほとんどのリスト(例えばgetElementsBy*querySelectorAll、およびNode.childNodesから返された)単純な配列ではなく、むしろNodeListオブジェクトではありません。 NodeListオブジェクトは通常「ライブ」です。そのため、ドキュメントへの変更は自動的にNodelistオブジェクトに伝播されます。

をだからあなたがいることを、あなたはすべてのa要素のNodeListをを取得した場合、その文書に別のa要素を追加し、あなたの例で見ることができるように(例外は生きる!ないである、querySelectorAllからの結果です) aがNodeListオブジェクトに表示されます。

これは、同時にドキュメントに変更を加えながらNodeListを反復処理することは安全ではないためです。たとえば、このコードは驚くべき動作をします:

var NodeListA = document.getElementsByTagName('a'); 

for (var i=0; i<NodeListA.length; ++i) { 
    // UNSAFE: don't do this! 
    NodeListA[i].parentNode.removeChild(NodeListA[i]); 
} 

要素がスキップされてしまいます。 NodeListの最後から逆方向に反復するか、NodeListをプレーンなArrayにコピーして(更新しません)、それを処理します。

ノードリストの詳細についてはMozilla MDC siteをご覧ください。

3

あなたがdocumentationを読めば、あなたは

驚かない指定されたタグ名を持つ要素のリストを返します。要素自体を除いて、指定された要素の下にあるサブツリーが検索されます。返されるリストはライブです。つまり、自動的にDOMツリーで更新されます。したがって、element.getElementsByTagNameを同じ要素と引数で複数回呼び出す必要はありません。 DOM内のノードの

関連する問題