Jintrick.netagenda2001年08月アーカイブ → 2001年08月12日

childNodesと改行コード

IEとMozillaで配列の中身がまるで違うという件。いろいろ試してみたところ、ようやく原因らしきものがわかった。

childNodes
A NodeList (英語) that contains all children of this node. If there are no children, this is a NodeList (英語) containing no nodes. The content of the returned NodeList (英語) is "live" in the sense that, for instance, changes to the children of the node object that it was created from are immediately reflected in the nodes returned by the NodeList (英語) accessors; it is not a static snapshot of the content of the node. This is true for every NodeList (英語), including the ones returned by the getElementsByTagName method.

DOM1(core) より

childNodesは、すべての子を含んだNodeList型で、The items in the NodeList are accessible via an integral index, starting from 0. とあるように0から始まる整数を経由してアクセスできるそうなのだから、childNodes[0]あるいはitemメソッドを用いてchildNodes.item(0)で、最初の子要素にアクセスできる筈。1から始まるなどというのはあり得ない。

テスト用リストその1
上のリストのソース
<ul id="testUL">
<li>test1</li>
<li>test2</li>
<li>test3</li>
</ul>
スクリプト
children = document.getElementById('testUL').childNodes;
document.write(children.length + '\n');
for(i=0; i<children.length; i++){
 document.write(children[i].innerHTML + '\n');
}
実行結果

Mozilla、N6の場合、これはどう解釈したものか。なぜchildren.lengthが、7 になるのか(IE5.5では期待通り3)。

そもそも、一応子Nodeとして数えられているがundefinedとなる、cihldNodes[0]は一体なんなのか。という話。

DOMでは、テキストも最終的なNodeとして扱われるらしい。ツリー構造なのだから当然だ。しかし、この中のどこにテキストがあるというのだろう。改行コードくらいしか入っていないよ。

というわけで、改行コードを取り払ってみると……。

テスト用リストその2(改行コード無し)
上のリストのソース
<ul id="testUL2"><li>test1</li><li>test2</li><li>test3</li></ul>
スクリプト
if(document.getElementById){
children = document.getElementById('testUL2').childNodes;
document.write(children.length + '\n');
for(i=0; i<children.length; i++){
 document.write(children[i].innerHTML + '\n');
}
}
実行結果

予想したとおりの結果に。

まとめ

Mozillaでは、childNodesに改行コードも含まれる。連続した改行コード、テキストは一つのNodeとして扱われる。試していないが恐らく半角スペースやタブ文字も同じだろう。

テキストがNodeとして扱われるのは良いが、改行コードを含めたところで一体何の用途があるというのだろう。ともかく、Mozillaでは添え字は1から始めて2ずつ足してゆかねば子のli要素は参照できない。或いは、ソースレベルで改行を取り払えばIEと同じ挙動になる。

良く言えば厳密な解釈。悪く言えば大きなお世話である。しかしそんなことよりも、IEがテキストを一つのNodeとして解釈しないことに驚いた。タグで明示されていようが、素のテキストであろうが、同じく子要素であるのに。これはDocument Object Modelの基本中の基本の部分 (英語)と矛盾しているといっていい、実に気持ちの悪いものだ。同じDOMでも、しかしDynamicHTML Object Modelであるといわれればそれまで。

ブラウザ判別はやはり免れないが、IE用のスクリプトをメインにするのは止めた。これからは動作確認は仕様書を眺めながらMozillaをメインに行ってゆくことにする。さもなければ私のような素人は、Document Object Modelを誤まって解釈しかねない。というか既にしている。


webmaster@jintrick.net
公開: 2001年08月12日
カテゴリ: