Join MDN and developers like you at Mozilla's View Source conference, 12-14 September in Berlin, Germany. Learn more at https://viewsourceconf.org

XBL で定義した要素へのプロパティの追加

続いては、XBL で定義された要素にカスタムプロパティを追加する方法を見ていきます。

XBL インタフェース

JavaScriptDOM は、要素のプロパティを取得または設定するためのアクセス手段を提供しています。 XBL を利用すれば、作成した要素に独自のプロパティを定義することが可能です。 または、処理を呼び出すためのメソッドを追加することもできます。 これらを行っておけば、後は (getElementById のような関数を使って) 要素への参照の取得を行うだけで、 追加したプロパティの取得や設定、または追加したメソッドの呼び出しが可能になります。

追加できる項目には 3 種類あります。

  • フィールド (field) は、単純な値を保持するのに使います。
  • プロパティ (property) も、値を保持するのに使いますが、値の取得や変更を行うときに、コードが実行される場合があります。
  • メソッド (method) は、実行可能な関数です。

これらの 3 つは、すべて binding 要素の子要素として置かれた implementation 要素の中に定義することになります。 implementation 要素の中では、 fieldpropertymethod の各要素を必要に応じて個別に定義していきます。 このための一般的な構文を以下に示します。

<binding id="element-name">
  <content>
    -- content goes here --
  </content>
  <implementation>
    <field name="field-name-1"/>
    <field name="field-name-2"/>
    <field name="field-name-3"/>

    <property name="property-name-1"/>
    <property name="property-name-2"/>
    <property name="property-name-3"/>
    .
    .
    .
    <method name="method-name-1">
      -- method content goes here --
    </method>
    .
    .
    .
  </implementation>
</binding>

フィールド

個々のフィールドは、 field 要素を使って定義します。 しばしば、フィールドは labeldisabled のような、 要素に置かれた属性と対応していますが、そうしなければならないという訳ではありません。

field 要素の name 属性は、フィールドの名前を指示するために使用します。 この名前を使用して、スクリプトからフィールドの値の取得と設定を行うことができます。 以下の例では、乱数を生成して保存するためのボタンを作成しています。 このボタンの number プロパティからは、(値を変更しない限り) 何回取得しても同じ値が取り出されることになります。 この例では、処理のほとんどを、 oncommand ハンドラで行っています。 これを XBL に移す方法については、もう少し後で見ることにします。

XUL:

<box id="random-box" class="randomizer"/>

<button label="Generate"
           oncommand="document.getElementById('random-box').number=Math.random();"/>
<button label="Show"
           oncommand="alert(document.getElementById('random-box').number)"/>

XBL:

<binding id="randomizer">
  <implementation>
    <field name="number"/>
  </implementation>
</binding>

このバインディングの中では、乱数を保存するための number フィールドが定義されています。 このフィールドの値の設定と取得は、XUL の方に追加した 2 つのボタンを使って行ないます。 そのための構文は、HTML 要素のプロパティの取得や設定を行うためのものによく似ています。 なお、この例では、表示するべきコンテントが XUL ボックスの中にも、対応する XBL の定義の中にも置かれていませんが、そのことはまったく問題ではありません。

といっても、この例のフィールドにはデフォルト値が設定されていないので、 この例には修正するべき点が 1 つもないという訳ではありません。 デフォルト値を設定するためには、field タグの内側にコンテントとして、デフォルト値として設定したい値を置きます。 以下に例を示します。

<field name="number">
  25
</field>

これによって、number フィールドのデフォルト値として 25 が設定されます。 さらに、値を置く代わりに field タグの中に、デフォルト値を求めるためのスクリプトを置くことも可能です。 この方法は、デフォルト値を計算する必要がある場合に必要になるはずです。 例えば、以下のフィールドは、現在時刻と同じ値がデフォルト値になります。

<field name="currentTime">
  new Date().getTime();
</field>

プロパティ

プロパティにデータを設定する際、値として正しいかを確認したいことはしばしばあると思います。 または、参照されるたびに動的に値を計算したい場合もあるかもしれません。 例えば、現在時刻を保持するプロパティが必要だとすると、その値は必要になるたびに生成したいはずです。 このような場合には、field タグではなく property タグを使う必要があります。 property タグを使う場合も、前述の field タグの場合と、構文自体は似ていますが、機能が追加されています。

onget 属性と onset 属性

プロパティでは、ongetonset 属性によって、値の取得または変更する場合にコードを実行させることが可能になります。 これらの属性は、property 要素に追加し、その値にはプロパティ値の取得、または設定を行なうためのスクリプトを設定します。

例えば、現在時刻を計算するためのスクリプトを onget に設定するとします。 この onget のスクリプトは、他のスクリプトがプロパティ値にアクセスするたびに、その値を取得するため呼び出されることになり、 このスクリプトは、そのプロパティの値となるべき値を返す必要があります。

また、onset ハンドラも似ていますが、こちらはスクリプトからプロパティに新しい値を設定しようとする場合に呼び出されることになります。 ここに設定するスクリプトは、値をどこかに保存するか、あるいは値が正しいかを確認するためのものになるはずです。 例えば、プロパティによっては、数値だけを保存できるようにしたい場合があると思いますが、 このようなプロパティに英字のテキストの設定を行おうとした場合は、失敗する必要があるはずです。

<property name="size"
          onget="return 77;"
          onset="alert('Changed to:'+val);"/>

このプロパティを取得すると、常に 77 を返します。 また、設定した場合には、値がプロパティに設定されたことを示すアラートが表示されます。 onset ハンドラが呼び出されるときには、特別な変数 val によって、プロパティに設定するべき値が渡されます。 ハンドラのスクリプトでは、これを利用して値が正しいかの確認や保存処理を行うことが可能です。 なお、onset ハンドラは、実際に設定された新しい値を返す必要があります。

続いては、スクリプトで「よくあるコード」が実行されたとき、 どのように処理されていくのかを見ていくことにします。

まず、「banana」と「orange」という名前の 2 つの要素があり、 それぞれには、「size」という名前のカスタムプロパティがあるとします。 このときに、以下のスクリプトを実行します。

banana.size = orange.size;
  1. orange の size プロパティを取得するために、orange の onget スクリプトが呼び出されます。呼び出されたスクリプトは値を計算して返します。
  2. banana の size プロパティの onset ハンドラが呼び出されます。onset のスクリプトでは val 変数を通して orange の onget スクリプトが返した値を受け取り、それを banana の size プロパティに必要な手順に従って設定します。

フィールドとは異なり、プロパティは値を保持しないことに注意してください。 onset ハンドラのないプロパティに値を設定しようとした場合は、エラーになります。 このため、しばしばプロパティの実際の値を保持するために、内部的に別のフィールドを利用します。 また、プロパティを XBL で定義された要素の属性に一致させる方法も、よく利用されます。 以下の例は、プロパティを要素の属性と対応させる方法を示しています。

<property name="size"
          onget="return this.getAttribute('size');"
          onset="this.setAttribute('size',val);"
/>

この例で作成したプロパティの値を、スクリプトから取得しようとするたびに、その要素の同じ名前の属性が取得されます。 また、設定しようとするときには、その値は要素の属性に設定されます。 こうしておけば、プロパティと属性のどちらから取得、または変更しても、同じ値になるため便利です。

getter 要素と setter 要素

また、onget 属性と onset 属性に設定するスクリプトが長い場合には、別の構文を利用することも可能です。 具体的には、onget 属性は、getter という名前の子要素として置き換えることができ、 onset 属性は、setter 要素で置き換えることが可能です。 以下に例を示します。

<property name="number">
  <getter>
    return this.getAttribute('number');
  </getter>
  <setter>
    var v = parseInt(val,10);
    if (!isNaN(v)) {
      this.setAttribute('number',''+v);
    }
  </setter>
</property>

この例のプロパティでは、整数値だけを保持することが可能です。 それ以外の文字が入力された場合は取り除かれます。 また、入力が数値でない場合には、値は変更されません。 これらの処理は、setter 要素の中に置かれたコードで行っています。 なお、このプロパティの実際の値は、要素の number 属性に保存されることになります。

プロパティ値の取得や設定を行なうハンドラを作成するためには、どちらの構文を利用しても構いません。

readonly 属性

field タグや property タグに readonly 属性を追加して true に設定することにより、 フィールドやプロパティを読み取り専用にすることが可能です。 このとき、読み取り専用になっているプロパティに値を設定しようとしても失敗します。

次のセクションでは、XBL で定義された要素にメソッドを追加する方法を見ていきます。

ドキュメントのタグと貢献者

 このページの貢献者: ethertank, Mgjbot, Morishoji
 最終更新者: ethertank,