Time Off for Good Behavior: Internet Explorer 5における DHTML Behavior

Dave Massy
Microsoft Corporation

Updated November 4, 1998     Posted June 11, 1998

編集者注: Behavior は、Internet Explorer 5の新しいオーサリング機能の多くと同様に、HTML 4.0やCSS2といったWorld Wide Web Consortium(W3C)の承認済みの標準の拡張案です。

Internet Explorer 5の新しい機能であるDHTML Behavior により、ドキュメントの中でDynamic HTMLの機能にアクセスしやすくなります。DHTML Behavior コンポーネントはJScript(R)やMicrosoft Visual Basic(R) Scripting Edition (VBScript)などの任意のスクリプティング言語で書くことができ、カスケーディング スタイル シート(CSS)を通してHTMLドキュメントの中の任意の要素に適用できるダイナミックな機能を提供します。

これはWebの開発者とオーサーにとってはどのような意味を持つのでしょうか? まず、ドキュメントの中でのDHTML Behavior の使い方を検討し、これによってDHTMLの世界にどのような恩恵がもたらされるかを考えてみましょう。

スクリプトとコンテンツの混在?

DHTMLは一般にページにインタラクティブ性と楽しみを与えてくれる素晴らしいテクノロジと見なされていますが、今日、DHTMLを使っているページが少ないのには1つの理由があります。基本的に、問題は、ドキュメントのコンテンツとダイナミックな機能のスクリプトを1つのファイルに混在させるという点にあります。

HTMLドキュメントのオーサリングを行っている多くの人にとって、ドキュメントにスクリプトを埋め込むことは、プログラマに通ずる滑りやすい坂道に向けて一歩を踏み出すということを意味しています(これはプログラマが悪い人たちだと言っているのではありません。私も時には自分でプログラムをするのですから!)。ドキュメントの中のスクリプトは複雑さと脆さをもたらし、何らかのコンテンツを変更しただけでスクリプトが正常に機能しなくなる可能性があります。オーサーがプログラミングの概念をよく理解し、スクリプトを使ってドキュメントにダイナミックな機能を追加している場合でも、同じファイルにスクリプトとコンテンツを入れていると、処理が遅くなり、管理が難しくなります。

DHTMLページの作成には3つの分野の人が関係します。コンテンツ プロバイダ、デザイナ、そしてエンジニアです。コンテンツ プロバイダはドキュメントのコンテンツの作成者であり、デザイナはドキュメントのルック アンド フィールを決定してフォーマッティング情報を追加し、エンジニアはスクリプトを使ってダイナミックな機能を追加します。CSSとDHTML Behavior を使うことで、ドキュメントのデザインとエンジニアリングの側面をコンテンツから分離し、各分野の専門家が他の分野との衝突を心配することなく、自分の領域に専念することができます。

DHTML Behavior はCSSを使って、スクリプトと、ドキュメントのコンテンツおよびスタイルを分離します。プログラマは、このような形で機能を分離することを「カプセル化」と呼んでいます。これにより、DHTMLの世界に再利用性の利点がもたらされます。

Flying, Behavior 不使用

次に、画面の左側からテキストを飛ばす例を示します。

<body onload=Bonload()>

<span delay=1000 id=Fly1>
This is some text
<img src=ie.gif>
<br>
This is some more text
</span>
<br>
<span delay=3000 id=Fly2>
This is some text
<img src=ie.gif>
<br>
More text
</span>
<br>
<span delay=5000 id=Fly3>
This is some text
<img src=ie.gif>
<br>
This is some more text
</span>
<br>
<span delay=7000 id=Fly4>
This is some text
<img src=ie.gif>
<br>
This is some more text
</span>

<script language="jscript">
var flyCount;
var msecs;

msecs = 50;
flyCount = 20;

document.all.Fly1.flying = false;
document.all.Fly2.flying = false;
document.all.Fly3.flying = false;
document.all.Fly4.flying = false;

document.all.Fly1.style.position = "relative";
document.all.Fly1.style.visibility = "hidden";

document.all.Fly2.style.position = "relative";
document.all.Fly2.style.visibility = "hidden";

document.all.Fly3.style.position = "relative";
document.all.Fly3.style.visibility = "hidden";

document.all.Fly4.style.position = "relative";
document.all.Fly4.style.visibility = "hidden";

function Bonload() {
  setTimeout("tick(document.all.Fly1)",
    document.all.Fly1.delay);
  setTimeout("tick(document.all.Fly2)",
    document.all.Fly2.delay);
  setTimeout("tick(document.all.Fly3)",
    document.all.Fly3.delay);
  setTimeout("tick(document.all.Fly4)",
    document.all.Fly4.delay);
}

function tick(elem)
{
   if (elem.flying) {
      doFly(elem);
   } else {
      fly(elem);
   }
}

function fly(elem) {
  elem.style.posLeft = -400;
  elem.style.visibility = "visible";
  elem.flying = true;
  flyTextIn(elem);
}

function flyTextIn(elem) {

  elem.oTop = elem.style.posTop;
  elem.oLeft = elem.style.posLeft;

  elem.currCount = 0;
  setTimeout("tick(document.all."
    + elem.id + ");", msecs);
}

function doFly(elem) {
  var dt, dl;

  elem.currCount++;
  dt = elem.oTop / flyCount;
  dl = elem.oLeft / flyCount;

  elem.style.posTop -= dt;
  elem.style.posLeft -= dl;

  if (elem.currCount < flyCount) {
      setTimeout("tick(document.all."
        + elem.id + ");", msecs);
  }
  else {
      elem.style.posTop = 0;
      elem.style.posLeft = 0;
      elem.flying = false;
  }
}

この例では、ページ上にコンテンツとスクリプトの両方が混在しています。この例はそれほど複雑ではありませんが、ページに機能を追加していけば、ますます複雑になり、保守が難しくなることは明らかです。

Flying, Behavior 使用

次に、DHTML Behavior を使って、左からテキストを飛ばす機能を実現している同じHTMLドキュメントのソースを示します。

<html>
<head>

<Style>
  .fly{behavior:url(fly.htc)}
</style>
</head>

<body>

<DIV class=fly delay=1000>
This is some text
<img src=ie.gif>
<br>
This is some more text
</DIV>
<br>
<DIV class=fly delay=3000>
This is some text
<img src=ie.gif>
<br>
More text
</DIV>
<br>
<DIV class=fly delay=5000>
This is some text
<img src=ie.gif>
<br>
This is some more text
</DIV>
<br>
<DIV class=fly delay=7000>
This is some text
<img src=ie.gif>
<br>
This is some more text
</DIV>

</body>
</HTML>

この例のドキュメントは主にコンテンツから構成されており、HTML コンポーネントファイル(.htc)に実装されている Behavior コンポーネントを使って、テキストを飛ばす機能を実現しています。これにより、ページのコンテンツを変更するときに他の機能を壊してしまうリスクが大幅に減り、ページの保守が容易になります。また、 Behavior コンポーネントは同じページで、または複数のページで何度でも使用することができます。この例の Behavior は、飛ぶテキストの向きと遅延時間を設定するための属性をいくつか公開しているので、ページ オーサーがスクリプトやオブジェクト モデルに関する知識を持っていなくてもドキュメントの中で簡単に使用できるコンポーネントが得られたことになります。

ドキュメント内でのDHTML Behavior の使用

では、HTMLドキュメントの中でDHTML Behavior を宣言し、使用するにはどうすればいいのでしょうか?

CSSの使い方がわかっている人であれば、DHTML Behavior の使い方もわかっていることになります。少しも難しいところはありません。World Wide Web Consortium(W3C)に対する提案では、behaviorという名前の新しいCSSプロパティが、 Behavior コンポーネントの位置を定義します。

前の例では、 Behavior コンポーネントfly.htcを含んでいるflyクラスを宣言していました。

<STYLE>
       .FLY{behavior:url{fly.htc}}
</STYLE>

このflyクラスは他のクラスと同様に任意のHTMLタグに使用することができます。

<DIV class=fly>
This text will fly
</DIV>

これにより、<DIV>の内容が飛ぶようになります。ドキュメントの中でHTMLとスクリプトを使って実現できるあらゆる効果を、DHTML Behavior を使って実現することができます。これにより、デザイナは、使い慣れたCSS構文を使ってエンジニアが準備したダイナミックな機能を簡単に適用できます。

しかしこれだけではありません。DHTML Behavior をInternet Explorer 5におけるXMLタグ サポートと組み合わせることによって、ページ オーサーはデフォルトの機能を公開する新しいタグを定義することができます。

このXMLの新機能とは?

Internet Explorer 5の素晴らしい機能の1つが、XMLを使って、HTMLドキュメントの中で使用できる新しいタグを定義できるということです。

XML名前空間を宣言するには、HTMLタグの中でxmlns属性を使用します。

<HTML xmlns:MYTAGS="urn:mytags" >

これは、XMLのMYTAGS名前空間をドキュメント内で使用することを宣言しています。<MYTAGS:TAGA>タグには、次のように標準的なHTMLコンテンツを入れることができます。

<MYTAGS:TAGA> This is some
  <B>Bold</B> HTML content </MYTAGS:TAGA>

これにはどのような利点があるのでしょうか? まず、ドキュメントに構造を導入して、コンテンツを分類することができます。たとえば、プロダクトと価格のリストを表示するドキュメントにおいて、プロダクトの説明を<PRODUCT:DESCRIPTION>タグに、価格を<PRODUCT:PRICE>タグに入れます。その後、ドキュメント内のすべての価格にアクセスするようなスクリプトを書くことができます。

では、これとDHTML Behavior の関係は? XMLタグにはCSSを適用することができます。したがって、ドキュメント内のすべての価格をピンク色で表示したい場合には、ドキュメントのヘッドの中に次のスタイルを宣言します。

 <STYLE>
  @media all{
    PRODUCT\:PRICE{color:pink}
  }
 <STYLE>

これで、ドキュメント内のすべての<PRODUCT:PRICE>タグの内容がピンクで表示されます。

DHTML Behavior はCSSプロパティとして提案されているのに過ぎないので、任意の新しいXMLタグにデフォルトの動作を適用することができます。前のfly Behavior の例に戻ると、任意のHTMLコンテンツをラップしてそのコンテンツを飛ばすことができるflyタグを宣言することができます。

<HTML xmlns:MYTAG="urn:mytags" >
<STYLE>
 @media all{    
   MYTAG\:FLY{behavior:url{fly.htc}}
 }
</STYLE>
.....
<MYTAG:FLY>
This text flies
</MYTAG:FLY>
</HTML>

ドキュメント オーサーは、他のドメイン内の他のサーバー上に置かれている Behavior を参照することができます。ただし、 Behavior を実装するする.htc ファイルが、ドキュメントのオーサーの知らないうちに移動または変更される可能性があるので注意する必要があります。したがって、自分のドメインの中にあり、通知なしには決して機能変更が行われない Behavior だけを使用するのが一番です。

どのようにDHTML Behaviorを作成するのか?

簡単です。HTMLと任意のスクリプティング言語を使って書けますし、ドキュメント内にスクリプトを埋め込むときとほとんど同じです。スクリプトは、HTMLコンポーネントか .htcファイルの中に記述し、 ドキュメントからBehavior 宣言によって参照されます。

DHTML Behavior では何ができますか。

  • 接続先のHTML要素の新しい属性とメソッドを公開することができます。ドキュメント オーサーからは、その要素の標準の属性とメソッドに見えます。
  • カスタム イベントを発生させることができます。ドキュメント オーサーからは、そのHTML要素の標準のイベントに見えます。
  • 接続先の要素にアクセスすることができます。したがって、ドキュメントのオブジェクト モデルを通して、ドキュメント全体にアクセスできます。
  • ドキュメント内の任意の場所のイベントを捕らえることができます。

HTC ファイルは2つの部分から構成されると考えられます。1つは、 Behavior の接続先の要素のプロパティ、メソッド、およびイベントとして公開されるプロパティ、メソッド、およびイベントの宣言です。もう1つはスクリプトです。

HTC ファイルの単純な例を示します。

<PUBLIC:METHOD name=mymethod />
<PUBLIC:PROPERTY name=myproperty />
<PUBLIC:EVENT ID=myEvent name=onMyEvent/ >
<SCRIPT>
...
</SCRIPT>

この Behavior は、1つのメソッド(mymethod)と1つのプロパティ(myProperty)を公開し、1つのカスタム イベント(onMyEvent)が発生します。HTMLドキュメントの中で使用すると、これらのプロパティ、メソッド、およびイベントが、 Behavior の適用先の要素で使用できる標準のプロパティ、メソッド、およびイベントに追加されます。プロパティ、メソッド、およびイベントを定義するとHTCファイルの残りの内容は、ドキュメント内のスクリプトとほとんど同じようにスクリプトを記述します。

タイミングの注意事項

Behavior コンポーネントがドキュメントのロード時にただちにHTML要素に接続されるとは限らないということを理解する必要があります。これは、.htcファイルが参照するドキュメントとは別のファイルであり、別途ダウンロードされるからです。このとき、HTMLドキュメントは依然としてダウンロード、解析、およびコンテンツの表示の途中である可能性があります。

ドキュメントと Behavior が解析され、ロードされている間、 Behavior はその進捗に関する通知を受け取ります。現時点では、contentChangedocumentReadyの2つの通知があります。contentChange通知は一番最初に1回受信されます。この通知は、 Behavior の接続先の要素の内容の解析が終わったことを知らせます。また、その後も、要素の内容が変化したときに受信されます。documentReady通知は、ドキュメントのダウンロードと解析が終わったときに受信されます。これは、ドキュメントのonLoadイベントとは違うことに注意してください。このイベントは、ドキュメントとそれに関連するすべてのデータが完全にインスタンス作成された時点で発火されます。 Behavior はドキュメントの任意のイベントを受信することができるので、必要ならばonLoadイベントも利用することができます。

.htc ファイルの中のインライン スクリプトは、 Behavior がインスタンス作成された時点で実行されます。ドキュメントに対して設定されている何らかの属性の値にアクセスする必要がある場合には、 Behavior は少なくとも最初のcontentChange通知が送られてくるまで待たなくてはなりません。インライン スクリプトが実行された時点で、これらの属性がまだ設定されていない可能性があるからです。

Dynamic List Behavior

次に、リスト要素に適用されたときに、リストの展開と縮小の機能を追加する単純な Behavior を示します。

<head>
<TITLE>UL with Behavior</TITLE>
<STYLE>
.LIST{behavior:url(ul.htc);}
</STYLE>
</head>

<body>
<p>This is an example
  of an expanding/collapsing list
  using DHTML Behaviors

<ul class="LIST" style="cursor: hand;"
  title="Click to toggle the List">
  This is an unordered list
  which has a behavior attached to the ul.
<li> Item 1
<li> Item 2
<li> Item 3
<li> Item 4
</ul>

</BODY>

次にスクリプレット ファイルを示します。このスクリプトは非常に単純で、ドキュメント本体に書かれるスクリプトに似ています。


<script language="jscript">

attachEvent("onclick", event_onclick);

function event_onclick()
{
   var i;
   var style;

   if (event.srcElement != element)
      return;

   for (i = 0; i < children.length; i++)
   {
       style = children[i].style;
       if (style.display == "none")
       {
           style.display = "";
       }
       else
       {
           style.display = "none";
       }
   }
}

</script>

結論

DHTML Behavior のパワーと柔軟性を実際に確かめたい方は、ぜひ sample gallery を訪れてください。スクリプト機能をドキュメントから除去することにはさまざまな利点がありますが、最も重要なのは保守と再利用の容易さです。コンテンツをスクリプトから分離することで、ダイナミックな機能を壊すリスクを犯さずにドキュメント コンテンツの保守を行うことができます。さらに、エンジニアが個々のドキュメントを保守しなくても、 Behavior を複数のドキュメントで再利用することができます。

DHTML Behavior をお楽しみください!

Dave Massy は古い Jaguar の車の復元を仕事にし、暇なときには Internet Explorer の Microsoft Program Manager として活動しています。ほとんどの時間は、Internet Explorer チームのメンバのところに足を運び、行儀よくするように頼む (modify their behavior) ことに費やしています。ただし、Dave はイギリス生まれなので、"bahavior" でなく "behaviour" と書くことがよくあります。