2011年12月20日火曜日

[JavaScript]childNodes と children で子ノードを取得する

いまさらですが知らなかったのでまとめました・・

childNodesプロパティ


JavaScriptでDOMを利用した処理をする場合、あるノードの子ノードを取得し、その子ノードに対して何らかの処理を行うというのは、よくあるパターンです。
今までの記事でも、子ノードを取得する場合、下記のように、DOMのchildNodesプロパティを使って取得していました。

サンプルHTML
<ul id="sample_list">
    <li>this</li>
    <li>is</li>
    <li>a</li>
    <li>test</li>
</ul>

サンプルコード
var ul = document.getElementById("sample_list");
var ch = ul.childNodes;
for (var i = 0, len = ch.length; i < len; i++) {
    console.log(ch[i].nodeName);
}

実行結果(以下すべて Chrome 16 で実行)
#text //改行がTextNodeとして取得されている
LI
#text
LI
#text
LI
#text
LI

上記のサンプルのように、childNodesプロパティで子ノードを取得した場合は、全ての子ノードのcollectionが返されます。 全ての子ノードということは、当然TextNode も含まれるので、改行やスペースがノードとして取得されています。 

通常、子ノードに対して処理をする場合、TextNodeは無視したい場合がほとんどなので、子要素のcollectionをフィルタリングする必要があります。 

サンプルコード
var ul = document.getElementById("sample_list");
var ch = ul.childNodes;
for (var i = 0, len = ch.length; i < len; i++) {
    if (ch[i].nodeName === 'LI'){
       console.log(ch[i].nodeName);
    }
}

実行結果
LI
LI
LI
LI

childrenで代用


childNodes の代わりに、childrenを使うと、TextNode は含まない、要素ノードだけのcollectionが返されます。
childrenは、IE6をはじめほぼ全てのブラウザで実装されているため、クロスブラウザの対応は特に必要ありません。

 サンプルコード
var ul = document.getElementById("sample_list");
var ch = ul.children;
for (var i = 0, len = ch.length; i < len; i++) {
    console.log(ch[i].nodeName);
}

実行結果
LI
LI
LI
LI

他にも要素ノードだけを対象にしたDOM非標準プロパティとしては、firstElementChild, lastElementChild, nextElementSibling などがありますが、children以外はブラウザによっては実装されていない場合があるので、使用には注意が必要です。

まとめ


子ノードの取得には、children がつかえる!

参考文献
ハイパフォーマンスJavaScript p50
ハイパフォーマンスJavaScript
ハイパフォーマンスJavaScript

0 件のコメント:

コメントを投稿