DOMのコレクション
DOMには「コレクション」という考え方があります。ページ上の互いに関連するオブジェクトをグループとしてとらえた概念です。コレクションは、documentオブジェクトやDOMノードなどのDOMオブジェクトのプロパティを通じて利用できます。例えばdocumentオブジェクトには、images、links、forms、anchorsといったコレクションがあります。これらのコレクションには、画像、リンク、フォーム、アンカーを表すすべての要素が入っています。図10.3は、linksコレクションを使ってページ上のすべてのリンクを抽出し、ページの下部にまとめて表示する例です。


このXHTMLのbody部では、テキストのあちこちにリンクをちりばめた段落(46~59行目)と、linksというidを持つ空のdiv(60行目)を指定しています。body要素のonload属性では、読み込みの終了時にprocesslinksメソッドを呼び出すよう指定しています。
processlinksメソッドでは、まず27行目でlinkslist変数を宣言し、documentオブジェクトのlinksプロパティで取得できるリンクのコレクションを格納しています。28行目では、ドキュメントのすべてのリンクを格納するための文字列(contents変数)を作成します。この文字列を、後でlinksのdivに挿入します。31行目から始まるforループでは、各リンクに対して反復処理を行います。コレクションに含まれる要素の数はコレクションのlengthプロパティで取得できます。
forループ内の33行目では、現在のリンクを格納したcurrentlink変数を作成しています。この例を見ても分かるように、linkslist内のコレクションにアクセスするには、配列と同様にインデックス番号を角かっこで囲んで指定します。DOMコレクションを格納したオブジェクトは、1つのプロパティ(lengthプロパティ)と2つのメソッド(itemメソッドおよびnamedItemメソッド)のみを持ちます。itemメソッドは、インデックスを角かっこで囲む記述方法の代わりになるもので、コレクション内の項目のインデックスを引数として指定すると、その項目にアクセスできます。namedItemメソッドは、名前を引数として渡すと、id属性またはname属性がその名前に一致する項目をコレクション内から見つけてくれるというものです。
34~36行目では、現在のリンクを格納するcontents変数の文字列にspan要素を追加しています。文字列オブジェクトのlinkメソッドは、現在の文字列を、引数で渡したURLへのリンクの形にして返します。35行目では、linkメソッドを使って、適切なテキストとhref属性を使用したa要素(アンカー)を作成しています。
この行を見ると分かるように、currentLink変数(要素を表すDOMノード)には、リンクのhref属性を表すhrefプロパティという特別なプロパティがあります。このようにXHTML要素の中には、基本的なDOMノードの機能を拡張した、特別な種類のノードとして表されるものが多くあります。39行目では、linksというidを持つ空のdiv(60行目)にcontents変数の内容を挿入しています。これにより、ページ上のすべてのリンクが1か所にまとめて表示されます。
コレクションを使うと、ページ上の同じ種類の要素すべてを簡単に操作できます。要素を1か所にまとめたり、ページ全体にわたって変更を加えたりする場合に便利です。例えば、フォームの送信ボタンが押された後で、formsコレクションを使ってフォームのすべての入力を無効にすれば、次のページを読み込むまでの間の多重送信を防ぐことができます。次のセクションでは、JavaScriptとDOMノードを使ってCSSのスタイルを動的に変更する方法を見ていきましょう。
動的なスタイル変更
要素のスタイルは動的に変更できます、こうした変更は、ユーザーの操作によるイベントに応じて行うことがよくあります(詳しくは第11章で解説)。スタイルの変更では、マウスのホバー効果、対話型のメニュー、アニメーションなど、さまざまな効果を作り出すことができます。図10.4はその簡単な例で、ユーザーの入力に応じてスタイルの背景色のプロパティを変更しています。



start関数(12~17行目)では、ユーザーに色の名前を入力させ、背景色をその値に設定しています(注:値が色として有効でない場合はエラーが発生します)。背景色の設定ではdocument.body.style.backgroundColorと指定しています。documentオブジェクトのbodyプロパティはドキュメントのbody要素を表します。そのstyleプロパティ(大半のXHTML要素にあるプロパティ)を使って、CSSのbackground-colorプロパティを設定します。ただしJavaScript上での表記はbackgroundColorとなります。CSSではハイフンが入りますが、減算演算子(-)との混同を避けるため、JavaScriptではハイフンがありません。この名前付け規則は、CSSのプロパティの大半に当てはまります。例えば、CSSのborder-widthはborderWidthと記述し、CSSのfont-familyはfontFamilyと記述します。一般に、CSSのプロパティは、node.style.stylepropertyという表記で操作できます。
図10.5では、windowオブジェクトのsetIntervalメソッドとclearIntervalメソッドを使い、動的なスタイルと組み合わせてアニメーション効果を作り出しています。この例は簡単なイメージビューアで、当社が執筆した書籍の表紙画像を選択して拡大表示できるというものです。右側でいずれかのサムネール画像をクリックすると、メインの画像エリアの左上からフルサイズの画像がアニメーション効果を使って拡大表示されます。
body部(66~85行目)にはdiv要素が2つあります。横に並べて表示するために、14行目と17行目のスタイル指定でそれぞれのfloatをleftとしています。左側のdivには、フルサイズ画像のiw3htp4.jpgを指定しており、ページの読み込み時にはこの画像が表示されます。右側のdivには、6つのサムネール画像を指定しています。クリックイベントの発生時には、displayメソッドを呼び出して、サムネールに対応する拡大版画像のファイル名を渡します。
display関数(46~62行目)では、ユーザーがクリックしたサムネールに応じて、左側のdivの画像を動的に更新します。48~49行目は、interval変数が定義されている場合(つまりアニメーションが進行中の場合)に関数の処理を行わないための措置です。51行目では、imgCoverというidを使って左側のdivを取得しています。52行目では、新しいimg要素を作成し、53~55行目では、その属性を設定しています。idはimgCover、srcはfullsizeディレクトリの適切な画像ファイルとし、必要なalt属性を設定しています。56~59行目は、61行目で開始するアニメーション処理に備えた追加的な初期化処理です。画像がだんだん大きくなっていくアニメーション効果を作成することから、57~58行目では画像の幅と高さを0に設定しています。59行目では、現在のbigImageノードを、52行目で作成したnewNodeに置き換え、60行目では、アニメーションの制御に使うcount変数を0に設定しています。
61行目では、windowオブジェクトのsetIntervalメソッドを使ってアニメーションを開始しています。このメソッドは2つのパラメータを取ります。1つは繰り返し実行するステートメント、もう1つはその実行間隔を表すミリ秒単位の整数です。この例のsetIntervalでは、10ミリ秒ごとに関数を呼び出すように指定しています。setIntervalメソッドは、この反復処理を追跡するための一意のIDを返します。この例ではその値をinterval変数に代入しています。画像がフルサイズまで拡大したら、このIDを使ってアニメーション処理を停止することになります。





run関数の定義は28~42行目にあります。この中では、画像の高さをspeed変数の値の分だけ大きくし、その高さと元の画像の比率に応じて幅を決定します。run関数は10ミリ秒ごとに呼び出されるため、この処理が繰り返され、画像がだんだん大きくなるアニメーション効果が実現できるというわけです。30行目で、speed変数(24行目で宣言、初期値は6)の値をcount変数に加えています。count変数はアニメーションの進行を制御し、現在の画像のサイズを決めるための変数です。画像の高さがフルサイズ(375)まで大きくなったら、35行目でwindowのclearIntervalメソッドを呼び出し、runメソッドの反復呼び出しを停止します。clearIntervalには反復処理を表す一意のIDを渡します。61行目でsetIntervalの戻り値としてinterval変数に格納しておいたIDです。この例の場合は、IDを使わなくてもよさそうに思えますが、複数の反復処理を並行して進める場合なら、このようにIDを使うことで、どの処理を停止するかをclearIntervalの呼び出し時に指定できます。
39行目では画像を取得し、40~41行目ではその幅と高さをCSSのwidthプロパティとheightプロパティで設定しています。40行目でcount変数の値に.7656を掛けているのは、画像の縦横比を元の画像と合わせるための措置です。このコードを実行してサムネール画像をクリックしてみれば、アニメーション効果を実際に確認できます。
このセクションでは、JavaScriptとDOMを使って、CSSのスタイルを動的に変更する方法を見てきました。また、setIntervalおよびclearIntervalを使って、スクリプトでアニメーション効果を作成する方法についても学びました。
DOMオブジェクトとコレクションのまとめ
ここまで見てきたように、W3CのDOMのオブジェクトとコレクションを使うと、Webページの要素を柔軟に制御できます。この章では、Webページのオブジェクトを操作する方法、オブジェクトのコレクションを操作する方法、要素のスタイルを動的に変更する方法を見てきました。
W3CのDOMでは、XHTMLドキュメントのすべての要素にアクセスでき、各要素はそれぞれ別個のオブジェクトとして表されます。図10.6は、W3CのDOMの重要なオブジェクトとコレクションをまとめた図で、図10.7は図10.6のオブジェクトとコレクションについての簡単な説明です。


W3Cのドキュメントオブジェクトモデルの詳細な情報については、DOM Level 3のW3C勧告(Document Object Model (DOM) Level 3 Core Specification)を参照ください。DOMのHTML仕様で最も新しいDOM Level 2 HTML Specification(Document Object Model (DOM) Level 2 HTML Specification)には、各種のXHTML要素に対応するオブジェクトなど、HTML固有のDOMの機能についても説明があります。ただし、仕様で定められた機能をすべてのWebブラウザが漏れなく実装しているわけではない点に注意してください。
