Jintrick.netagenda2007年12月アーカイブ → 2007年12月11日

セクション内容の参照について

div2 が認識可能であるか、XHTML で Pre-HTML 的に <div class="div2"> といった感じでマークアップしていれば、var div2 = document.getElementById('h-7.5').nextSibling; といった感じで id="h-7.5" な属性を持つ h2 要素の次の要素として div2 に相当する要素が取得でき、ここだけユーザに提供する、といった事が簡単に行えます。

Hack Or Die 2007/12 - Ancient libraryより

といった感じ、というわけでこれでは殆どのケースでdiv2相当のdiv要素を参照することはできない。これで参照できるのは、h2の終了タグとdivの開始タグが隣接していることが分かっている場合だけだ。普通はソース整形のためのテキストノードになってしまう場合が多いだろう。

ツリー構造の文書に対してnextSiblingでdiv2を参照するJavascriptコード例(対象:Firefox2)
// 見出し要素とdiv2相当の要素が並列している場合
var div2 = document.getElementById("h-7.5");
while(div2 = div2.nextSibling) {
    if (div2 instanceof HTMLDivElement && div2.isClassOf("div2"))
        break;
}

コメントアウトしているように、見出し要素(h2)とdiv2相当のdiv要素が兄弟要素として並列していると分かっている場合のコード。XHTMLは自由に構造化できるので、h2要素と他のヘッダ要素(日付とか)をもセクションヘッダ要素としてグループ化している場合もあり、本気でdiv2要素の参照を得ようと思ったらdocument order順に辿るといった「tree walk」でやらなければならない。XPathが使えるならfollowing-sibling軸で簡単にできるけど。

しかし、div2 を暗黙的に補助して解釈してくれるような実装は当然存在せず、実際にマークアップされている通りに解釈するため、上記のようなコードでは ISO HTML においては、次の h2 以上のレベルまでの要素をスキャンしたりするなどのコードが必要になります。

暗黙的ではダメで明示的である必要があるというのは、まさにこうした点で出てくる話です。こうした状況を想定している場合、W3C (X)HTML は採用できても ISO HTML を採用することは考えられません。

Hack Or Die 2007/12 - Ancient libraryより

この引用した部分を読んで、スキャンしたりするなどのコードを書けばいいんじゃないの? と考えた貴方へ。

フラットな文書のセクション内容をdiv2で参照するJavascriptコード(対象:Firefox2)
var range = document.createRange();
var currentNode = document.getElementById("h-7.5");
var level = currentNode.level;
range.setStartAfter(currentNode);
while(currentNode = currentNode.nextSibling) {
    if (currentNode instanceof HTMLHeadingElement
            && currentNode.level <= level) {
        range.setEndBefore(currentNode);
        break;
    }
    else if (currentNode instanceof HTMLDivElement
            /* && currentNode.selectNodes("child::address") */ ) {
        range.setEndBefore(currentNode);
        break;
    }
}
if (!currentNode)
    range.setEndAfter(document.body.lastChild)
var div2 = document.createElement("DIV");
div2.setAttribute("class", "div2");
range.surroundContents(div2);

ISO-HTML準拠の文書のように、フラットな構造が確定しているならセクション内容の参照は容易である。しかし実際の文書型宣言はHTML4.01とかにしておかないとスクリプト適用後にInvalidになってしまう罠があって、そのためISO-HTMLの場合、セクション単位でスタイルを指定するのは非常に困難である。CSSの神とかでない限りは。

そういうわけで、近藤さんのいうように、そういった状況ではISO HTML を採用することは考えられないが、但しdiv要素を使わず、単にセクション内容をデータ的に取得したいだけであるならその限りではない。


webmaster@jintrick.net
公開: 2007年12月11日
カテゴリ: DOM ,HTML