ドキュメントオブジェクトモデル
Dynamic HTMLのドキュメントオブジェクトモデルにより、Webドキュメントの個々のコンポーネント(個々のエレメントからコンテナまで)にプログラムからアクセスすることができる。これとイベントモデルの組み合わせによって、ブラウザはユーザーからの入力に反応し、その場でスクリプトを実行し、サーバーから追加のドキュメントをダウンロードすることなく新しいコンテントを表示できる。ドキュメントオブジェクトモデルを利用すると、HTMLオーサーは特別な技術を習得することなく、洗練されたインタラクティブ性を簡単に作成できる。
オブジェクトモデルとは?
オブジェクトモデルとは、Dynamic HTMLをプログラム化するメカニズムである。オーサーは、新しいHTMLタグやオーサリング技術を習得する必要はない。実際、オブジェクトモデルは、オーサーが今までのブラウザ用にコンテントを作成するために使用していた機能性を基にしている。Internet Explorer 3.0で、スクリプトのFORMエレメントに値を設定する場合や、リンクにmouseoverイベントを追加するにはどうしたかを思い出してみよう。オブジェクトモデルの限られたフォームを使用して、スクリプトによってHTMLにアクセスしていた。
現在のオブジェクトモデルの異なる点は、“すべての”HTMLエレメントをプログラム化できることである。これにより、ページ上のあらゆるHTMLエレメントにスクリプトを記述できるため、ユーザー アクションで動的にページのコンテントを変更できるのである。このイベントモデルは、ユーザーがページ上で行うこと(特定のエレメントにマウスを移動する、キーを押す、入力フォームに情報を入力するなど)に対してドキュメントを反応させる。各イベントは、新しいファイルのためにサーバーに戻ることなく、ブラウザにコンテントの変更を行わせるスクリプトとすぐにリンクできる。このため、オーサーはインタラクティブなWebサイトをより少ないページで作成でき、ユーザーはWebサーバーから新しページがダウンロードされるのを待つこともなくなり、ブラウジングが高速になり、Internet全体としてのパフォーマンスが向上する。
スクリプトでエレメントにアクセスする
すべてのHTMLエレメントは、オブジェクトモデルで定義されるスクリプトを作成できるオブジェクトであり、プロパティ、メソッド、イベントを持つ。しかし、各エレメントのオブジェクトにスクリプトを記述するには、オーサーがエレメントの取得方法を知らなくてはならない。
オブジェクトモデルは、エレメントを階層化しグループ化したエレメント コレクションを定義する。その中で最も重要なコレクションは、allコレクションとchildrenコレクションである。Dynamic HTMLドキュメントは、エレメントを構造化したものである。例えば、次に示す例のように、各エレメントは、それが置かれた場所によって変化する影響範囲を持つ。
<HTML>
<BODY>
<DIV>
<P>Some text in a <B>paragraph</B>
<IMG id=image1 src="mygif.gif">
</DIV>
<IMG id=image2 src="mygif.gif">
</BODY>
</HTML>
上記のDIVエレメントは、Pタグと、image1のIMGタグをを含んでいる(つまり、PタグとIMGタグの親である)。これに対して、image1とPは、DIVの子である。しかし、image2のIMGタグの場合、BODYエレメントの子である。そして、すべてのエレメントはHTMLエレメントの子である。
各エレメント オブジェクトは、allコレクションとchildrenコレクションを持つ。allコレクションには、その階層のエレメントの下にあるすべてのエレメントが含まれる。childrenコレクションには、そのエレメントで直接の子孫のエレメントだけが含まれる。上記の例では、BはDIVのallコレクションに入るが、DIVのchildrenコレクションには入らない。同様に、DIVはBODYのchildrenコレクションのメンバーだが、Pはそうではない。
各エレメントごとのこれらのコレクション以外に、(documentオブジェクトで表示される)ドキュメント自体には多くのエレメント コレクションと非エレメント コレクションがある。最も重要となるのが、Webページのすべてのエレメントを含むallコレクションである。このコレクションは、スクリプトからエレメントにアクセスする主要な方法となる。コレクションの利用については、エレメントとコレクションにおけるスクリプト記述を参照すること。
イベント-バブリング、キャンセル、処理
ボタンをクリックする、Webページ上にマウスを動かす、ページのテキストを選択する、といったアクションはすべてイベントを発生させる。このイベントには、DHTMLオーサーがイベントへの応答として実行するコードを記述できる。通常、この特別なコードはイベントを処理することから、イベントハンドラといわれる。
イベントの処理は、Internet Explorer 4.0でだけでなくInternet Explorer 3.xでも特別なことではない。Netscape Navigator 3.xとCommunicatorでも同様にイベントを処理できる。しかし、Internet Explorer 4.0では、イベントのソースであるWebページのHTMLエレメントと、生成されるイベントの型を非常に拡張している。今までは、限られたHTMLエレメント(アンカー、イメージマップ、FORMエレメント、アプリケーション、オブジェクト)だけがイベントを生成した。Internet Explorer 4.0のイベントモデルでは、ページのあらゆるHTMLエレメントすべてがマウスイベントとキーボードイベントにおけるソースとなることができる。
Internet Explorer 4.0における、あらゆるHTMLエレメントで生成する一般的なイベントを次に示す。
オーサーがコードを作成する際に、簡便さ、単純、保守の容易さを得られるように、Internet Explorer 4.0は新しいイベント処理方法を提供する。イベントバブルである。Windows®、OS/2、OSF Motif、そして他のGUIプラットフォームの大部分では、ユーザーインターフェイスのイベント処理にこの技術を使用している。しかし、イベントバブルはHTMLでは新しい技術である。これは、オーサーがWebドキュメントにイベント処理を取り込むための効果的なモデルを提供する。
今までは、HTMLエレメントでイベントを生成してもイベントハンドラが登録されていない場合、そのイベントは蒸発したように消えてしまう。イベントバブルは、その未処理のイベントを親エレメントに渡し、処理を任せる。イベントは処理されるまで、または、最上位のオブジェクト(documentオブジェクト)に到着するまで階層を上がり続ける("バブルアップ")。
イベントバブルの利点
- 複数エレメントに共通の処理をまとめられる
- Webページ全体におけるコードの量を削減できる
- ドキュメントを更新する際に必要となるコード変更の数を削減できる
次に、アクションにおけるイベントバブルの簡単な例を示す。
<html>
<body>
<div id=OuterDiv style="background-color: red" onmouseover="alert(window.event.srcElement.id);">
This is some text
<img id=InnerImg>
</div>
</body>
</html>
この例は、ユーザーがテキストにマウスポインタを移動すると、"OuterDiv"というメッセージのダイアログボックスが表示される。マウスを画像に移動すると、"InnerImg"というメッセージのダイアログボックスが表示される。
この例で注意すべき個所は、IMGエレメントに対するonmouseoverイベントが、イベントハンドラがないのに処理されたことである。その理由は、IMGエレメントからのonmouseoverイベントがその親エレメント(DIVエレメント)までバブルアップしたからである。DIVにはonmouseoverイベントのために登録されたイベントハンドラがあるので、イベントを受け取り、指定されたイベント処理を実行する。
イベントが発生するたびに、windowオブジェクトに特別なプロパティが作成される。この特別なプロパティにはeventオブジェクトが含まれる。eventオブジェクトには、発生したイベントのコンテキスト情報、マウスの位置、キーボードの状態、そして(一番重要な)イベントのソースエレメントなどが含まれる。
ソースエレメントはイベントの発生を引き起こしたエレメントで、window.eventオブジェクトのsrcElementプロパティでアクセスできる。
上記の例では、ダイアログボックスにイベントのsrcElementのidプロパティを表示している。
ロールオーバー効果の処理
オーサーは、ページの一部にユーザーがマウスを移動すると反応し、ロールオーバー効果を起こすようにできる。Internet Explorer 4.0では、ロールオーバー効果の作成は非常に単純化されている。
<html>
<head>
<style>
.Item {
cursor: hand;
font-family: verdana;
font-size: 20;
font-style: normal;
background-color: blue;
color: white
}
.Highlight {
cursor: hand;
font-family: verdana;
font-size: 20;
font-style: italic;
background-color: white;
color: blue
}
</style>
</head>
<body>
<span class=Item>Milk</span>
<span class=Item>Cookies</span>
<span class=Item>Eggs</span>
<span class=Item>Ham</span>
<span class=Item>Cheese</span>
<span class=Item>Pasta</span>
<span class=Item>Chicken</span>
<script>
function rollon() {
if (window.event.srcElement.className == "Item") {
window.event.srcElement.className = "Highlight";
}
}
document.onmouseover = rollon;
function rolloff() {
if (window.event.srcElement.className == "Highlight") {
window.event.srcElement.className = "Item";
}
}
document.onmouseout = rolloff;
</script>
</body>
</html>
この例では、7つのSPANエレメントが最初に(インラインスタイルの)Itemクラスを使うように設定されている。これらのエレメントの1つにマウスを移動すると、Highlightクラスに変更される。
Internet Explorer 4.0での新規機能で、以下のことが可能となった。
- SPANエレメントはイベントを発生できるが、今まではすべてのSPANをアンカーで囲んでイベントを取得しなくてはならなかった。
- イベントバブルにより、イベントをdocumentオブジェクトで取得できる。そのため、効果を与える各エレメントごとに、別々のイベントハンドラを作成する必要がない。例えば、オーサーがページにエレメントを追加する場合、まったくスクリプトを変更せずにイベントモデルにそのエレメントを追加することができる。documentオブジェクトはドキュメント全体のすべてのエレメントの"最上位の親"である。
イベントのキャンセル
すべてのイベントは、そのイベントがキャンセルされない限り親エレメントまで(再帰的にdocumentオブジェクトまで)バブルアップする。イベントをキャンセルするには、イベントハンドラでwindow.event.cancelBubbleプロパティを"true"に設定する。キャンセルされるまで、イベントは階層をバブルアップし、既にイベントが処理されていても、登録されているすべての親エレメントのハンドルで処理される。
イベントバブルのキャンセルは、イベントに対するデフォルトアクションのキャンセルと区別しなくてはならない。いくつかのイベント(例えば、アンカーのonclickイベント)には、デフォルトアクションがある。アンカーがクリックされた場合のデフォルトアクションは、srcプロパティで指定されたURLに現在のウィンドウをナビゲートすることである。イベントハンドラから"false"が返されたり、window.event.returnValueに"false"を設定するとデフォルトアクションをキャンセルできるが、window.event.cancelBubbleを設定しないかぎりイベントバブルはキャンセルできない。逆に、イベントバブルをキャンセルしても、デフォルトアクションはキャンセルされない。
最後に、特定のエレメントすべてに対して共通のイベント処理を適用している際のイベントバブルの扱いについて説明する。次の行のエレメントについてだけ、イベント処理の適用を排除するにはどうすればよいか?
<span class=Item>Ham</span>
上の行を以下のように変更するだけである。
<span class=Item onmouseover="window.event.cancelBubble = true;" onmouseout="window.event.cancelBubble = true;">Ham</span>
これで、"Ham"にマウスを何度も移動しても、スタイルは変更されない。これは、onmouseoverイベントとonmouseoutイベントの両方のイベントハンドラで、イベントバブルがキャンセルされたからである。documentオブジェクトにイベントがバブルアップしないので、documentオブジェクトでは"Ham"に対するこれらのイベントを処理する機会が与えられない。
onmouseoverイベントの効果的な利用法
どのような場合でも、1つのオブジェクトだけにonmouseoverイベントが起こるようにすることができる。この場合を次に示す。
<DIV id=MyDiv>
<IMG id=MyImg>
</DIV>
IMGにマウスを移動すると、次の順番でイベントが起こる。
MyDiv:: onmouseover
MyDiv:: onmouseout
MyImg:: onmouseover
IMGからマウスを移動すると、再びMyDiv::onmouseoverイベントが発生する。
いくつかの特別な効果を与えるために、マウスがDIVの外側に移動したことを検出しなければならない場合がある。onmouseoutイベントに渡すだけでは十分ではない。これを簡単に処理できるように、Internet Explorer 4.0ではonmouseoverイベントとonmouseoutイベントで、ソースエレメント(fromElement)とターゲットエレメント(toElement)を取得できる。containsメソッドとこれらのプロパティをいっしょに使用することで、マウスが範囲外に出たことを検出できる。
これらのプロパティとcontainsメソッドを使う例を次に示す。
<html>
<body id=Body>
<div id=OuterDiv style="width: 100px; height: 50px; background: red"
onmouseover="over();" onmouseout="out();">
<img id=Img1>
<img id=Img2>
<img id=Img3>
</div>
<script>
function over() {
var s;
s = "onmouseover: "+window.event.srcElement.id+" from: "+
window.event.fromElement.id+" to: "+window.event.toElement.id;
alert(s);
}
function out() {
var s;
s = "onmouseout: "+window.event.srcElement.id+" from: "+
window.event.fromElement.id+" to: "+window.event.toElement.id;
alert(s);
if (!(OuterDiv.contains(window.event.toElement))) {
alert("Out Now");
}
}
</script>
</body>
</html>
トップに戻る
© 1997 Microsoft Corporation. All rights reserved. Terms of Use.