Hatena::ブログ(Diary)

三等兵

2010-12-20

Element Traversal API

今更ながらJavaScriptのDOM Core基礎 - 三等兵の付け足し。あの記事長いので重くて開けない。

http://www.w3.org/TR/ElementTraversal/


なんぞ?

firstChildとかlastChildとかが便利になったやつ。空白ノードとかコメントノードとか無駄なノードをよけて、要素ノード(nodeTypeが1)しか手を出しません。


やってみる

// js
var oda = document.getElementById('love_story');
alert(oda.firstChild.nodeType); // 3(テキストノード)
alert(oda.firstElementChild.nodeType); // 1

alert(oda.lastChild.nodeType); // 3(テキストノード)
alert(oda.lastElementChild.nodeType); // 1

// html
<ul id="love_story">
  <!-- コメ -->
  <li>あの〜ひ</li>
  <li>あの〜とき</li>
  <li>あ〜のばしょ〜で</li>
  <li>きみ〜にラリアットォォオ!</li>
  <!-- コメ -->
</ul>

Element Traversal APIの種類

今のところインターフェースはこれら。

  • firstElementChild
  • lastElementChild
  • previousElementSibling
  • nextElementSibling
  • childElementCount

名前でだいたいどういうものか予想できると思いますが従来のと比較してみると分かりやすい。

従来Element Traversal
firstChildfirstElementChild
lastChildlastElementChild
previousSiblingpreviousElementSibling
nextSiblingnextElementSibling
childNodes.lengthchildElementCount

基本的には従来の考え方で問題ないけれど、違いはElement Traversal APIだと要素ノードしか手を出さないということ。空白ノードやコメントノードを除去する処理を書く手間が省けますね。


ちなみにElement Traversal APIは元々SVG名前空間のSVG Tiny 1.2仕様の一部として公開されたみたいです。

The ElementTraversal interface was originally published as part of the SVG Tiny 1.2 specification in the SVG namespace.

Element Traversal API

サンプル。後述の対応ブラウザで試してください。


firstElementChild

その要素の最初の子要素ノードを参照。

//js
var list = document.getElementById('love_story');
alert(list.firstElementChild.firstChild.nodeValue);  // あの〜ひ

// html
<ul id="love_story">
  <!-- コメ -->
  <li>あの〜ひ</li>
  <li>あの〜とき</li>
  <li>あ〜のばしょ〜で</li>
  <li>きみ〜にラリアットォォオ!</li>
  <!-- コメ -->
</ul>

lastElementChild

その要素の最後の子要素ノードを参照。

//js
var list = document.getElementById('love_story');
alert(list.lastElementChild.firstChild.nodeValue);  // きみ〜にラリアットォォオ!

// html
<ul id="love_story">
  <!-- コメ -->
  <li>あの〜ひ</li>
  <li>あの〜とき</li>
  <li>あ〜のばしょ〜で</li>
  <li>きみ〜にラリアットォォオ!</li>
  <!-- コメ -->
</ul>

previousElementSibling

その要素の直前の要素ノードを参照。

//js
var li02 = document.getElementsByTagName('li')[2]; // <li>あ〜のばしょ〜で</li>の要素
alert(li02.previousElementSibling.firstChild.nodeValue); // あの〜とき

// html
<ul id="love_story">
  <!-- コメ -->
  <li>あの〜ひ</li>
  <li>あの〜とき</li>
  <li>あ〜のばしょ〜で</li>
  <li>きみ〜にラリアットォォオ!</li>
  <!-- コメ -->
</ul>

nextElementSibling

その要素の直後の要素ノードを参照。

//js
var li02 = document.getElementsByTagName('li')[2]; // <li>あ〜のばしょ〜で</li>の要素
alert(li02.nextElementSibling.firstChild.nodeValue); // きみ〜にラリアットォォオ!

// html
<ul id="love_story">
  <!-- コメ -->
  <li>あの〜ひ</li>
  <li>あの〜とき</li>
  <li>あ〜のばしょ〜で</li>
  <li>きみ〜にラリアットォォオ!</li>
  <!-- コメ -->
</ul>

childElementCount

その要素のすべての子要素ノードの個数を返す。

//js
var list = document.getElementById('love_story');
alert(list.childNodes.length);  // 13
alert(list.childElementCount);  // 4

// html
<ul id="love_story">
  <!-- コメ -->
  <li>あの〜ひ</li>
  <li>あの〜とき</li>
  <li>あ〜のばしょ〜で</li>
  <li>きみ〜にラリアットォォオ!</li>
  <!-- コメ -->
</ul>

childNodes.lengthとの違いに注目。


childNodesに変わるものがない

なんでchildNodesに変わるchildなんちゃらが無いのかと。調べてみたら、

http://ejohn.org/blog/element-traversal-api/

johnさんが指摘してた。childElementsみてーなもんはねーのかよボケと。でもchildrenってのがあるんだよサバ缶野郎、だって。口悪いのは脚色。


childrenというプロパティがある

IEだけのものだと思っていたけれど、最近の主要なブラウザでは普通に実装されているみたい。これはchildNodesのElement Traversal API版と考えれば良い。

//js
var list = document.getElementById('love_story');

alert(list.childNodes.length); // 13

alert(list.children.length); // 4
alert(list.children[0].firstChild.textContent); // あの〜ひ

// html
<ul id="love_story">
  <!-- コメ -->
  <li>あの〜ひ</li>
  <li>あの〜とき</li>
  <li>あ〜のばしょ〜で</li>
  <li>きみ〜にラリアットォォオ!</li>
  <!-- コメ -->
</ul>

childeNodesと同じ感覚で扱えて、その上無駄なノードの除去の処理も書かなくてかなり便利。


とはいえIE8以下の

childrenはchildeNodesと同じです。なのでIE8以下とIE9のchilrenはまったく別ものなので注意。


難点

firstElementChildとかなげえよ。でもそんな説明的な名前がJavaScriptらしい。


対応ブラウザ

http://www.quirksmode.org/dom/w3c_traversal.html

  • IE9(pp3)
  • Firefox3.5
  • Opera10.10
  • Chorome5
  • safari4 win

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証