DynamicHTMLとは、スクリプトなどを使ってDOM(Document Object Model)を操作し、ブラウザに動的な効果を与える技術です。DOMに対し、Netscape6.0以降のFirefoxをはじめとしたMozilla系ブラウザではJavaScript、Internet ExplorerではJScriptを使ってアクセスする手段が用意されています。

 DOMは、HTMLやXMLで記述したドキュメントを、プログラムから参照・操作できるようするための技術です。ブラウザなどに実装された機能や情報、タグなどの要素やスタイルシート、要素やスタイルシートが持つ属性などを、オブジェクト化および構造化する方法を仕様として定めています。

 DOMの仕様は、現在W3CによりDOM Level 3まで公開されています。FirefoxやInternet Explorer、Opera、Safari、Chromeなど、現在主流となっている多くのブラウザで積極的にサポートされています。

 DOMの採用により、HTMLドキュメント上のあらゆるタグ要素やスタイルシートのプロパティにアクセスできます。これにより、これまで以上に多彩な表現をブラウザ上で実現可能になりました。特に、スタイルシートはオブジェクトの位置や可視属性などを細かく設定できるので、それをJavaScriptでコントロールすれば劇的な効果をブラウザに与えられます。Ajaxでは、受け取ったデータのブラウザへの表示部分でDynamicHTMLの技術が使われています。

ブラウザのDOMの実装状況

 DOMは、Internet Explorerではバージョン4.0サポートされています。また、Mozilla系ブラウザでもNetscape6.0からDOMがサポートされています。これにともない、Netscape6.0以降のMozilla系ブラウザでは、JavaScript1.3以前のバージョンで言うところの、ナビゲータ・オブジェクトの部分がDOMに置き換わり、そのDOMをJavaScriptを使って操作するようになりました。

 Internet Explorer4.Xのころは、W3CでDOMの仕様が規格化される前だったこともあり、DOMにアクセスし操作するための方法は、独自色の濃いものでした。同じくDOMの規格化以前のNetscape4.Xも、コンテンツの位置決めにスタイルシートや独自仕様のレイヤーを使い、オブジェクトの動きをJavaScriptで設定してサイトに動的な効果を与えることをDynamicHTMLと呼んでいました。

そのため、当時NetscapeとInternet Explorerの両者で、DynamicHTMLを実現する方法には大きな違いがありました。また、Netscape4.XやInternet Explorer4.Xのころは、スタイルシートに関しても違いがあり、両方のブラウザを対象にしたDynamicHTMLを作成するためには、この点にも気をつける必要がありました。

 このように、以前はDynamicHTMLを使ったサイトを構築しようとした場合、ブラウザ間の仕様の違いを埋め合わせるため、多くの労力やテクニックが必要でした。しかし、スタイルシートやDOMの仕様が確定した後に発表されたNetscape6.0以降のFirefoxを含めたMozilla系ブラウザやInternet Explorer5.0以降からは、ほぼ同じ方法でスタイルシートの設定やDOMへのアクセスを実施可能となっています。

 また、Opera、Safari、Chromeなどの後発のブラウザは、当初から標準化がおこなわれた仕様を積極的に取り入れて開発されたこともあり、DOMやスタイルシート、JavaScriptを元に標準化がおこなわれたスクリプト言語であるECMAScriptなど、DynamicHTMLを実現するために必要な仕様が当初よりサポートされています。このため、これらのブラウザでは、基本的にFirefoxやバージョン5.0以降のInternet Explorerと同じ用法で、DynamicHTMLを実現することができます。

ブラウザへのDOMの実装

 FirefoxやInternet ExplorerなどのDOM対応ブラウザでは、DynamicHTMLの実現に必要な、JavaScriptのナビゲータオブジェクトにあたる、ブラウザ自身が持っているユーザエージェント情報や来歴といった情報や表示にかかわる各要素を、図1のようなwindow要素をルート(頂点)としたツリー構造として持っています。このツリー構造では、img要素やform要素、style要素などの、ブラウザに表示するコンテンツに関する要素、つまりタグ要素やstyle要素は、document要素がルートとなり、すべてその下に集められています。

図1●DOMの階層

 DOMの場合、各要素が持つ値のことを属性といいます。DOMの要素や属性もオブジェクトであり、DOMの要素や属性は、JavaScript的な言い方をすれば、要素(element)はオブジェクト(object)、属性(attribute)はプロパティ(property)と置き換えられます。そして、このツリー上の各要素(element)や属性(attribute)の一つずつがノード(node)となります。

 ノードは、ツリー構造にしたがって親子関係を持っています。この親子関係は、どのノードから見るかによって変化します。例えば、document要素から見ると、window要素は親(parent)ノードに、img要素は子(child)ノードになります。また、window要素から見ると、document要素は子ノード、img要素は孫ノードとなります。同様に、img要素が持つsrc属性やalt属性などの属性も、img要素から見るとimg要素が持つ属性は子ノードとなり、属性側から見るとimg要素は親ノードとなります。

 DOMは、HTMLドキュメントも各要素をノードとして構造化します。例えば、図2のようなHTMLドキュメントの場合、p要素から見るとbody要素は親ノードとなり、em要素やa要素は子ノードになります。そして、この場合も起点となるノードが変わると親子関係も変化します。例えば、同じHTMLドキュメントをbody要素から見ると、p要素は子ノードになり、em要素やa要素は孫ノードとなります。

図2 HTMLドキュメントの例
<html>
    <head>
        <mata>
        <title> ~ </title>
    </head>
    <body>
        <h1> ~ </h1>
        <p>
            <em> ~ </em>
            <a> ~ </a>
        </P>
    </body>
<html>

 このように、DOMを利用したページを作成する場合は、構造的にHTMLやスタイルシートを記述する必要があります。HTMLやスタイルシートは、それぞれの仕様に準拠した記述をする必要性がますます高くなってきているといえるでしょう。

DOMとJavaScript

 DOMは、ブラウザの持つ情報や機能に対しインタフェースを用意しているだけで、プログラミング言語ではありません。しかし、そのインタフェースを通してJavaScriptなどから各要素にアクセスし操作することで、DynamicHTMLやXML、これらを統合したAjaxのページを作れるようになっています。

 ブラウザに実装されているDOMの構造は、JavaScriptのナビゲータオブジェクトの構造と似ています。すなわち、ルートがwindow要素で、Frame要素やhistory要素、document要素がwindow要素の子ノードとなり、img要素やform要素およびstyle要素などのブラウザに表示するコンテンツに関する要素がdocument要素の下に集められている、という構造です。

 navigator要素やscreen要素がwindow要素の子ノードになっているなど細かな部分での違いがありますが、元々windowオブジェクトの記述は省略可能だったので、この点も問題になりません。このようなDOMの構造のおかげで、JavaScriptと同じような感覚でDOMの各要素を取り扱えます。特に、window要素やnavigator要素、screen要素などは、JavaScriptと同じ用法で各要素を取り扱えます。

 DOMには、DOMの要素や属性を取り扱うための多くのプロパティやメソッドが用意されています。そしてその中には、DynamicHTMLのページを作るのに必要なものだけでなく、XMLのページを作るために用意されているものもあります。ここでは、その中でも特に、DynamicHTMLのページを作る上で必要となるプロパティやメソッドを中心に紹介しています。

DOMのイベントの取り扱い

 DOMでのイベントの取り扱いは、JavaScriptとほぼ同じです。ただし、JavaScriptが特定のタグ要素から特定のイベントしか取得できなかったのに対し、DOMでは、body要素も含めて、body要素内のあらゆるタグ要素からイベントハンドラを使ってイベントを取得できます。

 イベントハンドラのうち、タグ要素に共通して取得できるイベントは次の通りです。

click, dblclick, keydown, keypress, keyup, mousedown, mousemove, mouseout, mouseover, mouseup

 また、button属性やtext属性を設定したフォームのinput要素は、次のイベントも取得できます。

change,select

 この他、body要素のloadおよびunload、form要素のsubmitおよびresetなど、これまでJavaScriptで対応していたイベントに関しては、従来通りそのままイベント取得ができます。