NodeIteratorのサンプル

サンプル1

よく わからない
うひょー
ノード一覧:

ソース1

<table class="sample" id="smp1">
<tr>
 <td>よく</td>
 <td>わからない</td>
</tr>
<tr>
 <td>表</td>
 <td>うひょー <!-- ←アホかこいつは --></td>
</tr>
</table>
var tdfilter = {};
tdfilter.acceptNode = function(node){
  return node.nodeName.toLowerCase() == 'td' ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP ;
};

function tditerator(){
  if(document.implementation.hasFeature("Traversal","2.0")){
    var it = document.createNodeIterator(document.getElementById('smp1'), NodeFilter.SHOW_ALL, tdfilter, false);
    iteratortest(it);
    it.detach();
  }
}

function tableiterator(){
  if(document.implementation.hasFeature("Traversal","2.0")){
    var it = document.createNodeIterator(document.getElementById('smp1'), NodeFilter.SHOW_ALL, null, false);
    iteratortest(it);
    it.detach();
  }
}

function iteratortest(it){
  var texttodisplay = "";
  while(pointednode = it.nextNode()){
    texttodisplay += "nodeName:" + pointednode.nodeName + "\t nodeValue:" + pointednode.nodeValue + "\n";
  }
  document.getElementById('iteratednodelist').firstChild.nodeValue = texttodisplay;
}

余談。Opera 9でテストした感じ、この程度の処理なら速度的な旨みは全然ない。 childNodes, getElementsByTagName > NodeIterator > NodeIterator + NodeFilter。 もっと複雑なことをさせるのには有効かもしれないけど、 そういうことをしようとすると今度はNodeIteratorに対応するブラウザが少なすぎてどうにもならない。

余談2。NodeFilterはDOMの仕様的にはこのサンプルのように作るべきだと思う。 しかし、実はacceptNodeに相当する関数だけでもいいらしい。つまり、

function tdfilter(node){
  return node.nodeName.toLowerCase() == 'td' ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP ;
}

でもいいようだ。というか、Safari 3ではこの書き方でないと正しく動かなかった。なんでだー! くやしいけどSafariでも動いたほうがいいかなと思って実は実行例はこっちを使っている。