HTML Components を使った DHTML Behaviors のスクリプトによる実装

Dynamic HTML (DHTML) Behaviors は、さまざまな方法で実装できるコンポーネントです。最初の数年間このコンポーネントの作成は、C++、Microsoft® Visual Basic®、Java などを使用する開発者に限られていました。

Microsoft® Internet Explorer 5 では、スクリプトの開発者が HTML Components (HTC) または Windows Scripting Components (WSC) を使って DHTML Behaviors を実装することができます。ここでは、Microsoft® Visual Basic® Scripting Edition (VBScript) や Microsoft® JScript® (ECMA 262 言語仕様互換)、あるいは Microsoft ActiveX® Scripting インターフェイスをサポートしているサードパーティのスクリプト言語を使用できます。

この記事では、HTC を使って DHTML Behaviors を実装する手順を大まかに説明します。WSCによる実装手順については、Microsoft Scripting  を参照してください。

ここでは、読者がスクリプトのプログラミングや HTC および DHTML Behaviors に精通しているものとして説明を進めます。C++ による Behavior の実装については、ここでは取り上げていません。DHTML Behaviors、HTC、WSC、および Behavior 実装に関わる C++ インターフェイスの詳細については、「関連トピック」を参照してください。

この記事を最後まで読み終えたら、特定のスクリプト言語で Behavior を実装でき、スクリプトとコンテンツを分離できるようになります。また、Web サイトでカプセル化やコードの再利用性といった利点を享受できるようになります。

この記事は次のセクションからなります。

  • HTC の概要
  • HTC の作成
  • プロパティの公開
  • メソッドの公開
  • カスタムイベントの公開
  • 通知の受信
  • スコープ規則
  • タイミングに関する留意事項
  • Behavior に関連した DHTML オブジェクトモデルの機能拡張
  • 関連トピック

HTC の概要

Internet Explorer 5 で導入された HTC は、DHTML Behaviors を実装するための簡単な機構を提供します。HTCファイルとは、.htcという拡張子付きで保存される HTML ファイルにすぎません。このファイルは、コンポーネントを定義するプロパティ、メソッド、およびイベントを公開する HTC 固有の一群のカスタム要素とスクリプトからなります。

HTML ファイルである HTC は、DHTML と同様、ページ上の全ての要素にアクセスできます。つまり、HTC 内であれば、全ての HTC 要素は ID 属性を使用してオブジェクトとしてスクリプトからアクセスすることができます。これにより、HTC 要素の属性とメソッドはすべて、オブジェクトのプロパティおよびメソッドとしてスクリプトを通じて動的に扱うことが可能となります。

Web 制作者は、HTC を使ってプロパティ、メソッド、カスタムイベントを公開する Behavior を実装できます。

  • プロパティとメソッドの公開。これらはそれぞれ PROPERTY 要素 と METHOD 要素を使って定義します。プロパティとメソッドの公開については、「プロパティの公開」と「メソッドの公開」を参照してください。
  • カスタムイベントの公開。このイベントは、EVENT 要素によって定義され、その要素の fire メソッドによってそのページ上での発生が可能となります。また、createEventObject メソッドにより、HTC はイベントを発生するときにイベントコンテキスト情報を設定することができます。イベントの公開については、「カスタムイベントの公開」を参照してください。
  • ページの DHTML オブジェクトモデルへのアクセス。HTC の element オブジェクトは、 Behavior が結合している要素を返します。このオブジェクトにより、HTC はそのドキュメントとオブジェクト モデル(プロパティ、メソッド、イベント)にアクセスできます。

ここに記した HTC の要素、プロパティ、メソッド、およびイベントの詳細については、HTC Reference を参照してください。

HTC の作成

HTC は次の手順で作成できます。この例は、カーソルを置いたときに要素がハイライトされるマウスオーバーハイライト効果を実装する場合を示しています。

  1. 骨格となる HTC ファイルの作成

  2. SCRIPTブロックには、 Behavior を実装するコードを書き込みます。

  3. この HTC を実装すると、ページ上で望みのマウスオーバーハイライト効果を与えることができます。

  4. 典型的な HTC ファイルは、SCRIPT ブロックとそれを囲むオプションの COMPONENT ブロックから構成されます。このファイルは .htc という拡張子を付けて保存します。

    <PUBLIC:COMPONENT>
        <SCRIPT>
        </SCRIPT>
    </PUBLIC:COMPONENT>
    
  5. SCRIPTブロックには、 Behavior を実装するコードを書き込みます。

  6. この HTC を実装すると、ページ上で望みのマウスオーバーハイライト効果を与えることができます。

  7. 次のコードでは、ATTACH 要素を使って、要素上での onmouseover および onmouseout イベント発生時に関する情報を HTC 側で受け取れるようにします。これによって、HTC はカーソルが要素上に来たらその要素の色をハイライトさせることができます。

    サンプルコード

    
    <PUBLIC:COMPONENT>
    <PUBLIC:ATTACH EVENT="onmouseover" ONEVENT="Hilite()" />
    <PUBLIC:ATTACH EVENT="onmouseout"  ONEVENT="Restore()" />
    <SCRIPT LANGUAGE="JScript">
       var normalColor, normalSpacing;
    
       function Hilite()
       {
         // save original values
         normalColor  = runtimeStyle.color;  
         normalSpacing= runtimeStyle.letterSpacing;
    
         runtimeStyle.color  = "red";
         runtimeStyle.letterSpacing = 2;
       }
    
       function Restore()
       {
         // restore original values
         runtimeStyle.color  = normalColor;
         runtimeStyle.letterSpacing = normalSpacing;
       }
    </SCRIPT>
    </PUBLIC:COMPONENT>
    

    注: 「HTC の概要」で述べたように、element オブジェクトは、 Behavior が結合している要素を返し、要素のオブジェクトモデルにアクセスできるようにします。あるいは、element キーワードを頭に付けずにプロパティ名、メソッド名、またはイベント名を使って要素のプロパティ、メソッド、イベントにアクセスすることもできます。前の例では、element.runtimeStyle (これも使用可)を使わずに runtimeStyle プロパティを直接参照して色がトグルされる点に注意してください。

  8. この HTC を実装すると、ページ上で望みのマウスオーバーハイライト効果を与えることができます。

  9. 
    <HEAD>
    <STYLE>
       LI {behavior:url(hilite.htc)}
    </STYLE>
    </HEAD>
    
    <P>Mouse over the two list items below to see this effect.
    <UL>
      <LI>HTML Authoring</LI>
      <LI>Dynamic HTML</LI>
    </UL>
    
    

    この機能は、Internet Explorer 5 以上を必要とします。その最新版をインストールするには、下のアイコンをクリックしてください。インストールが完了したら、このページを再ロードしてサンプルを表示してみてください。

    Microsoft Internet Explorer

プロパティの公開

HTC は、PROPERTY 要素を使ってそれ自身のプロパティ セットを公開できます。

たとえば、前のマウスオーバーハイライトのサンプルを拡張して、Web 制作者がハイライトしたいテキストの色を設定できるよう hiliteColor プロパティを公開することができます。これを行うときには、次のコードに示されているように、PROPERTY 要素を使ってプロパティを定義します。


<PUBLIC:PROPERTY NAME="hiliteColor" />

プロパティを定義したら、次のコードのように HTC のコード内でそれを参照することができます。ページでその値を設定していない限り、このコードはプロパティ値を赤に設定する点に注意してください。


<PUBLIC:PROPERTY NAME="hiliteColor" />
<PUBLIC:ATTACH EVENT="onload" FOR="window" ONEVENT="initColors()"  />

<SCRIPT LANGUAGE="JScript">
function initColors()
{
  // initialize the property
  hiliteColor = (hiliteColor == null) ? "red" : hiliteColor;
}
</SCRIPT>  

次の例では、マウスオーバー ハイライト効果が目次に適用されており、カーソルがテキストの上にくるとアンカーの色が変化します。この最初のリストでは、カーソルが置かれるとアンカーの色が緑に変化しますが、2番目のリストではアンカーの色が既定値の赤に変わるだけということに注意してください。先ほど触れたように、当該ページで hiliteColor プロパティを設定していない限り、既定値の赤が使用されます。


<style>
   .CollapsingAndHiliting {behavior:url(ul.htc) url(hilite2.htc)} 
   A           {behavior:url(hilite2.htc)}
</style>

<UL>
  <LI CLASS="CollapsingAndHiliting" CHILD="Topics1">HTML Authoring</LI>
  <UL ID="Topics1">
      <LI><A HILITECOLOR="green" HREF="/workshop/author/default.asp">Beginner's Guide</A></LI>
      <LI><A HILITECOLOR="green" HREF="/workshop/author/default.asp">IE4.0 Authoring Tips</A></LI>
      <LI><A HILITECOLOR="green" HREF="/workshop/author/default.asp">HTML Coding Tips</A></LI>
      <LI><A HILITECOLOR="green" HREF="/workshop/author/default.asp">Table Cell Backgrounds</A></LI>
      <LI><A HILITECOLOR="green" HREF="/workshop/author/default.asp">Drop Caps</A></LI>
      <LI><A HILITECOLOR="green" HREF="/workshop/author/default.asp">Quote Server</A></LI>
      <LI><A HILITECOLOR="green" HREF="/workshop/author/default.asp">HTML Wizard</A></LI>
      <LI><A HILITECOLOR="green" HREF="/workshop/author/default.asp">Dr. HTML</A></LI>
      <LI><A HILITECOLOR="green" HREF="/workshop/author/default.asp">HTML Coding FAQ for Internet Explorer</A></LI>
      <LI><A HILITECOLOR="green" HREF="/workshop/author/default.asp">SGML DTD for Internet Explorer 3.0 Markup</A></LI>
      <LI><A HILITECOLOR="green" HREF="/workshop/author/default.asp">Authoring Basics</A></LI>
      <LI><A HILITECOLOR="green" HREF="/workshop/author/default.asp">Authoring Effective Pages</A></LI>
      <LI><A HILITECOLOR="green" HREF="/workshop/author/default.asp">Designing Efficient Pages</A></LI>
      <LI><A HILITECOLOR="green" HREF="/workshop/author/default.asp">Using Frames</A></LI>
  </UL>
   <LI><A HREF="/workshop/author/default.asp">HTML Help Authoring</A></LI>
   <LI CLASS="CollapsingAndHiliting" CHILD="Topics2">HTML References</LI>
   <UL ID="Topics2">
      <LI><A HREF="/workshop/author/default.htm">Elements</A></LI>
      <LI><A HREF="/workshop/author/default.htm">Character Sets</A></LI>
   </UL>
   <LI CLASS="CollapsingAndHiliting" CHILD="Topics3">HTML Applications (HTA)</LI>
   <UL ID="Topics3">
      <LI><A HREF="/workshop/author/default.htm">Overview</A></LI>
      <LI><A HREF="/workshop/author/default.htm">Reference</A></LI>
   </UL>   
</UL>

この機能は、Internet Explorer 5 以上を必要とします。その最新版をインストールするには、下のアイコンをクリックしてください。インストールが完了したら、このページを再ロードしてサンプルを表示してみてください。

Microsoft Internet Explorer

注: 任意の要素に対して定義済みの名前と同名のプロパティを公開すれば、この Behavior のほうがその要素のデフォルト Behavior を上書きします。たとえば、href プロパティを公開している Behavior がページ上の A 要素に適用されると、この Behavior が A 要素の既定値の href プロパティを上書きします。

INTERNALNAME 属性の使用

HTC でプロパティを公開するときには、PROPERTY 要素内の NAME 属性と INTERNALNAME 属性の両方を指定できます。両方の名前を指定すると、NAME は HTC を含んでいる文書からプロパティを参照するのに、また INTERNALNAME は HTC 内の同じプロパティを参照するのに使用されます。

プロパティで INTERNALNAME 属性を指定する場合は、コンポーネント内の任意の箇所でそれを参照する前に、あらかじめ変数名をグローバルに宣言し、初期化する必要があります。そうしないと、変数名の未定義を示すスクリプトエラーが生じるか、その HTC を含む文書で不正なプロパティ値が取得されます。

PROPERTY の宣言で PUT 属性か GET 属性を指定すると、INTERNALNAME が指定されていても、INTERNALNAME 属性は無視されます。PUT や GET 属性で指定した関数によるプロパティ値の設定、取得は、INTERNALNAME によるプロパティ値の設定、取得よりも優先されます。

メソッドの公開

次に示すコードのように、METHOD 要素を使用すれば、HTC はそれ自身のメソッドの一式を公開することができます。


<PUBLIC:METHOD NAME="startFlying" />

メソッドを定義したら、次のサンプルコードのように HTC コード内でそれを使用することができます。これは、ページ上のテキストグループの浮動(flying)効果を実装したものです。


<PUBLIC:METHOD NAME="tick" />
<PUBLIC:METHOD NAME="startFlying" />
:
<SCRIPT LANGUAGE="JScript">
var currCount;
var flyCount;
var flying;
var msecs;
var oTop, oLeft;

msecs = 50;
flyCount = 20;
flying = false;

runtimeStyle.position = "relative";
runtimeStyle.visibility = "hidden";

window.attachEvent("onload", onload);

function onload()
{
  // delay commences from the window.onLoad event
  if (delay != "none")
  {
     window.setTimeout(uniqueID+".tick()", delay);
  }
}


function tick()
{
   if (flying == false)
   {
      startFlying();
   }
   else
   {
      doFly();
   }
}

function startFlying()
{
  if (fromX==null && fromY==null)
  {
     if (from=="top")
     {
       runtimeStyle.posTop = -offsetTop-offsetHeight;
     }
     else if (from=="bottom")
     {
       runtimeStyle.posTop = element.document.body.clientHeight;
     }
     else if (from=="right" )
     {
       runtimeStyle.posLeft = element.document.body.clientWidth;
     }
     else 
     { 
       runtimeStyle.posLeft = -offsetLeft-offsetWidth;
     }    
  }
  else
  {
     runtimeStyle.posTop = fromY;
     runtimeStyle.posLeft = fromX;
  }

  runtimeStyle.visibility = "visible";
//  runtimeStyle.display = "";
  flying = true;

  oTop = runtimeStyle.posTop;
  oLeft = runtimeStyle.posLeft;

  currCount = 0;
  doFly();
}

function doFly()
{
  var dt, dl;

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

  runtimeStyle.posTop -= dt;
  runtimeStyle.posLeft -= dl;

  if (currCount < flyCount)
  {
      window.setTimeout(uniqueID+".tick();", msecs);
  }
  else
  {
      runtimeStyle.posTop = 0;
      runtimeStyle.posLeft = 0;
      flying = false;
      evObj = createEventObject();
      evObj.setAttribute("resulty", uniqueID);  
      finished.fire(evObj);
  }
}
</SCRIPT>

この機能は、Internet Explorer 5 以上を必要とします。その最新版をインストールするには、下のアイコンをクリックしてください。インストールが完了したら、このページを再ロードしてサンプルを表示してみてください。

Microsoft Internet Explorer

注: PROPERTY 要素の場合と同様、METHOD 宣言で INTERNALNAME を指定できるので、ページ内でのメソッドの参照名と HTC 内での参照名は異なります。また、要素に対して定義済みの名前と同名のメソッドを公開すれば、この Behavior のほうがその要素のデフォルト Behavior よりも優先されます。たとえば、click メソッドを公開した Behavior がページ上の A 要素に適用されると、この Behavior のほうが A 要素のデフォルトの click メソッドよりも優先されます。

カスタムイベントの公開

EVENT 要素を使って、HTC はカスタムイベントを定義し、それを当該ページに公開できます。

次のコードは、HTC として実装された電卓が EVENT 要素を使ってどのようにカスタムイベント(onResultChange)を定義するかを示したものです。イベントが当該ページ上で発生すると、そのとき取得された値がページに返され、結果としてイベントオブジェクトの expando プロパティが設定されます。


<PUBLIC:EVENT NAME=onResultChange ID=rcID />
 
<SCRIPT LANGUAGE="JScript">
   :
   oEvent = createEventObject();
   oEvent.result = sResult;
   rcID.fire (oEvent);
   :
</SCRIPT>

次のサンプルは、ページの外観を示すコードです。


<HTML XMLNS:InetSDK>
<HEAD>
<TITLE>Calculator Sample</TITLE>

<STYLE>
   INPUT    {font-family: Courier New}
   @media all {
      InetSDK\:CALC {behavior:url(Engine.htc)} 
   }
</STYLE>

<LINK REL="stylesheet" HREF="/workshop/basicSDKIE4.css" TYPE="text/css">
</HEAD>

<BODY BGCOLOR="#FFFFFF">
<BLOCKQUOTE CLASS="body">

<P>
<InetSDK:CALC id="myCalc" onResultChange="resultWindow.innerText =window.event.result">


<TABLE>
<TR>
<TD COLSPAN=5>
<DIV ID="resultWindow" STYLE="padding:5; background-color:buttonface" ALIGN="RIGHT">0.</DIV>
</TD>
</TR>
<TR><TD><INPUT TYPE=BUTTON VALUE=" 7 "></TD>
    <TD><INPUT TYPE=BUTTON VALUE=" 8 "></TD>
    <TD><INPUT TYPE=BUTTON VALUE=" 9 "></TD>
    <TD><INPUT TYPE=BUTTON VALUE=" / "></TD>
    <TD><INPUT TYPE=BUTTON VALUE=" C "></TD>
</TR>
<TR><TD><INPUT TYPE=BUTTON VALUE=" 4 "></TD>
    <TD><INPUT TYPE=BUTTON VALUE=" 5 "></TD>
    <TD><INPUT TYPE=BUTTON VALUE=" 6 "></TD>
    <TD><INPUT TYPE=BUTTON VALUE=" * "></TD>
    <TD><INPUT TYPE=BUTTON VALUE=" % " DISABLED></TD>
</TR>
<TR><TD><INPUT TYPE=BUTTON VALUE=" 1 "></TD>
    <TD><INPUT TYPE=BUTTON VALUE=" 2 "></TD>
    <TD><INPUT TYPE=BUTTON VALUE=" 3 "></TD>
    <TD><INPUT TYPE=BUTTON VALUE=" - "></TD>
    <TD><INPUT TYPE=BUTTON VALUE="1/x" DISABLED></TD>
</TR>
<TR><TD><INPUT TYPE=BUTTON VALUE=" 0 "></TD>
    <TD><INPUT TYPE=BUTTON VALUE="+/-"></TD>
    <TD><INPUT TYPE=BUTTON VALUE=" . "></TD>
    <TD><INPUT TYPE=BUTTON VALUE=" + "></TD>
    <TD><INPUT TYPE=BUTTON VALUE=" = "></TD>
</TR>
</TABLE>

</InetSDK:CALC>

</BLOCKQUOTE>
</BODY>
</HTML>

この機能は、Internet Explorer 5 以上を必要とします。その最新版をインストールするには、下のアイコンをクリックしてください。インストールが完了したら、このページを再ロードしてサンプルを表示してみてください。

Microsoft Internet Explorer

注: 要素に対して定義済みの名前と同名のイベントを公開すれば、この Behavior は、その要素のデフォルト Behavior を上書きします。たとえば、onclick イベントを公開した Behavior がページ上の A 要素に適用されると、この Behavior が A 要素のデフォルトの onclick イベントを上書きします。

通知の受信

HTC は、ATTACH 要素を通じて当該ページで発生するイベントに結合できます。この要素を使って、HTC は標準の DHTML イベント、それに HTC Reference に記載された HTC 固有のイベントに結合できます。

注: HTC は、attachEvent メソッドで当該ページから通知を受信することができます。ただし、これには次のような欠点があります。

  • attachEvent メソッドでは、標準の DHTML イベントに結合できるだけで、HTC 固有のイベントにはいっさい結合できません。
  • HTC は、 Behavior が要素から分離された後も、ページから通知を受信し続けます。しかし、HTC は ondetach イベント発生時に detachEvent メソッドを呼び出すことができます。ATTACH 要素を使ってページ上のイベントに結合する Behavior は、その要素から切り離されると、通知の受信を自動的に停止します。

スコープ規則

HTC を使って作業をするときには、3つの名前空間、すなわち Behavior 、要素、およびページの名前空間が関わってきます。HTC についてはスコープ規則が定義されており、これによって名前の競合を防ぐ優先順位を設けることができます。この競合解消用の優先順位には、上から順に次のようなレベルがあります。

  1. Behavior
  2. Behavior が結合する要素
  3. HTC を含む文書の window オブジェクト

これは、HTC で event というグローバル変数が定義されている場合は、HTC 内の event への参照はそのグローバル変数に名前解決されますことを意味します。その HTC 内のwindow オブジェクトのイベントプロパティは、window.event を使うことで正しく参照できます。

次の例では、前述したスコープ規則を使って名前解決が処理されるしくみに注目してください。

  • attachEvent - 要素の attachEvent メソッドに解決されます。これは、element.attachEvent を呼び出すのと同じことです。
  • normalColor - スクリプトの先頭の Behavior で定義されたグローバル変数に解決されます。
  • runtimeStyle - 要素の runtimeStyle プロパティに解決されます。

<SCRIPT LANGUAGE="JScript">
var normalColor, normalSpacing;

attachEvent("onmouseover", event_onmouseover);
attachEvent("onmouseout",  event_onmouseout);

function event_onmouseover()
{
  // save original values
  normalColor  = style.color;  
  normalSpacing= style.letterSpacing;
 
  runtimeStyle.color  = "red";
  runtimeStyle.letterSpacing = 2;
}
function event_onmouseout()
{
  // restore original values
   runtimeStyle.color  = normalColor;
   runtimeStyle.letterSpacing = normalSpacing;
}

</SCRIPT>

タイミングに関する留意事項

Behavior を編集するときには、Behavior がいつ要素に適用されるか分かっていることが重要です。Behavior が適用されるまで、Behavior を定義したプロパティの値(ドキュメントから設定できる)にスクリプトからアクセスすることはできません。

Behavior が完全にダウンロードされ、それが要素に適用されるためには、onreadystatechange イベントの発生を待ち、要素の readyState プロパティが complete に設定されたことを確認することが重要です。このイベントが発生するまでは、 Behavior が要素に結合しないうちに Behavior を定義したメンバを使おうとすると、オブジェクトがその特定のプロパティまたはメソッドをサポートしていないことを示すスクリプトエラーが発生する場合があります。

注: Behavior や HTC を含む文書が解析され、ロードされるときに、その Behavior は oncontentready および ondocumentready 通知により progress の通知を受け取ります。oncontentready 通知は、要素のコンテンツが完全に解析されたときに受信されます。この時点で、 Behavior は要素の innerHTML プロパティに基づいて適正な値を返すことができます。ondocumentready 通知は、スクリプト全体、イメージ、ActiveX コントロール、個別にダウンロードする必要のある他のすべてのファイル(ページ上の)などのドキュメントが完全にダウンロードされたときに受信されます。

Behavior に関連した DHTML オブジェクトモデルの強化

Internet Explorer 5 では、Behavior のサポートを追加することにより、次のように DHTML オブジェクトモデルを強化しています。

  • 提案中の カスケーディングスタイルシート(CSS) behavior 属性は、その Behavior を要素に適用します。
  • HTC は、attachEvent および detachEvent メソッドにより、オブジェクト上でのイベント発生時に呼び出される関数を指定して、HTC を含むページからの通知を受信したり、受信を停止したりすることができます。
  • HTC は、uniqueID プロパティにより、ID 属性を要素に割り当てることができます。これが大いに役立つのは、HTC がコードをページに挿入する場合や、 Behavior の適用される要素の ID を指定する必要がある場合などです。
  • addBehavior および removeBehavior メソッドを使用すれば、CSS を使わずにページ上の要素に対して Behavior を動的に結合、分離することができます。
  • behaviorUrns コレクションは、要素に結合されているすべての Behavior の URN を識別します。
  • イベントオブジェクトの srcUrn プロパティでは、イベントを発生させた Behavior の URN を指定します。
  • scopeName および tagUrn プロパティでは、要素に定義された名前空間を一斉に識別します。
  • urns メソッドは、指定の Behavior がその時点で結合されているすべてのオブジェクトを識別します。

関連トピック

DHTML Behaviors の補足情報については、次のリンクを参照してください。