続いては、XBL で定義された要素にイベントハンドラを追加する方法について見ていきます。
イベントハンドラ
通常の XUL の場合と同じように、XBL がバインドされた要素で発生したマウスクリックやキーの押し下げなどのイベントは、そのままコンテントの中にある個々の要素にも送られていきます。 XBL の場合には、イベントをトラップして処理するときにも専用の方法を用いる必要があると予測していたかもしれませんが、 前のセクションの最後の例で示したように、XBL のコンテントの中に置かれた要素には、必要に応じてイベントハンドラを追加することが可能です。 そのときの例では、いくつかのボタンに対して
ハンドラの追加を行いました。oncommand
handler 要素
しかしながら、コンテント全体、つまり
タグの中で定義されたすべての要素を対象にしたイベントハンドラを追加したい場合もあると思います。 これは、フォーカスイベントやブラーイベントをトラップするような場面で役に立つはずです。 このようなイベントハンドラは、content
要素を使用して定義できます。 この要素には、単一のイベントハンドラと対応するアクションを記述していきます。 また、必要なら、複数のハンドラを使用することも可能です。 イベントが handler
の対象イベントのどれともマッチしない場合は、通常の場合と同じように、単に内側のコンテントに送られることになります。handler
一般的なハンドラの構文は、以下のようになります。
<binding id="binding-name"> <handlers> <handler event="event-name" action="script"/> </handlers> </binding>
ハンドラはすべて、
要素の中に置きます。 個々の handlers
要素では、handler
event
属性で指定した特定のイベントを処理するためのアクションを定義します。 イベントには、click
や focus
といった、XUL と JavaScript でサポートしている種類のものであれば指定することが可能です。 なお、使用するイベント名の最初に「on」を付けないことに注意してください。
このハンドラは、イベントが発生したときにカスタムプロパティを変更するために、よく利用されます。 例えば、カスタムチェックボックスを作成する場合には、 checked プロパティを、利用者がチェックボックスをクリックしたときに変更する必要があるかもしれません。
<handlers> <handler event="mouseup" action="this.checked=!this.checked"/> </handlers>
上記のチェックボックス上で、利用者がマウスボタンをクリックして放したとき、 mouseup
イベントが送出されて、ここで定義したハンドラが呼び出されます。 その結果、checked
プロパティの状態が反転します。 また、同様に要素がフォーカスを得たときにプロパティを変更したい場合もあると思います。 このとき、場合によっては特殊なスタイルプロパティ -moz-user-focus
を利用して、 要素がフォーカス可能であるか否かを変更する必要があるかもしれません。 このプロパティによって、要素がフォーカス可能かどうかを制御することが可能です。 (参照: フォーカスと選択)
マウスイベントを処理する
マウスイベントの場合、button
属性を使用することで、 ハンドラに対して特定のボタンで起こったイベントだけをトラップするように指定することが可能です。 この属性がない場合には、ハンドラは、どのボタンが押された場合のイベントでも全てトラップすることになります。 button
属性に設定する値には、左マウスボタンを対象にする場合は「0
」、中央マウスボタンの場合は「1
」、右マウスボタンの場合は「2
」を設定します。
<handlers> <handler event="click" button="0" action="alert('Left button pressed');"/> <handler event="mouseup" button="1" action="alert('Middle button pressed')"/> <handler event="click" button="2" action="alert('Right button pressed');"/> </handlers>
キーイベントを処理する
また、キーイベントの場合は、マッチさせるキーを指定したり、特定の修飾キーが押されている場合だけマッチするように限定したりするために、 XUL の
要素が持っている属性に類似した、いくつかの属性を使用することが可能です。 前の例を拡張して、スペースバーが押された場合に、チェックボックスの key
checked
プロパティの変更を行うようにする例を以下に示します。
<handlers> <handler event="keypress" key=" " action="this.checked=!checked"/> </handlers>
また、文字で表すことのできないキーをチェックするために、keycode
属性を使用することも可能です。 なお、キーコードの指定値など、さらに詳細な情報については、キーボードショートカットのセクションを参照してください。 また、修飾キーについては、modifiers
属性を追加することでチェックできます。 ここには、以下の値のいずれかを設定します。
- alt
- 利用者が、Alt キーを押す必要があります。
- control
- 利用者が、Control キーを押す必要があります。
- meta
- 利用者が、Meta キーを押す必要があります。
- shift
- 利用者が、Shift キーを押す必要があります。
- accel
- 利用者が、そのプラットフォームで通常キーボードショートカットを呼び出すために使われる修飾キーを押す必要があります。
上記を設定すると、ハンドラはその修飾キーが押されていた場合のみ呼び出されます。 また、これらをスペースで区切って指定することで、複数の修飾キーが押されている場合のみに限定することも可能です。
ハンドラで行うコードが複雑な場合、以下のような構文を代わりに使用することができます。
<binding id="binding-name"> <handlers> <handler event="event-name"> -- handler code goes here -- </handler> </handlers> </binding>
ハンドラの例
以下の例では、キーのハンドラをいくつか追加することで、単純なローカルのクリップボード機能を作成しています。
例 1 : ソース
<binding id="clipbox"> <content> <xul:textbox/> </content> <implementation> <field name="clipboard"/> </implementation> <handlers> <handler event="keypress" key="x" modifiers="control" action="this.clipboard=document.getAnonymousNodes(this)[0].value; document.getAnonymousNodes(this)[0].value='';"/> <handler event="keypress" key="c" modifiers="control" action="this.clipboard=document.getAnonymousNodes(this)[0].value;"/> <handler event="keypress" key="v" modifiers="control" action="document.getAnonymousNodes(this)[0].value=this.clipboard ? this.clipboard : '';"/> </handlers> </binding>
コンテントには、テキスト入力欄が 1 つだけあります。 また、クリップボードの内容を保存するために clipboard
フィールドが追加されています。 このため、このクリップボードの操作対象は、この 1 つのテキストボックスのみに限られるということになります。 ただし、この要素を複数生成した場合には、個々のクリップボードは、それぞれでバッファを持つことになるので互いの操作が干渉することはありません。
3 つのハンドラが、切り取り、コピー、貼り付けのために追加されています。 それぞれのハンドラには、呼び出すためのキーストロークが設定されています。 最初のハンドラは、切り取り操作で、Control キーと x キーが押された場合に呼び出されます。 action
属性に置かれたスクリプトでは、テキスト入力欄のテキストの切り取りと、clipboard
フィールドへの保存を行います。 この例は、単純化するため、選択された部分のテキストを切り取るのではなく、単にテキスト全体の切り取りを行います。 このとき、このコードは以下のように動作します。
-
this.clipboard=document.getAnonymousNodes(this)[0].value;
匿名コンテント配列の最初の要素、つまり、content
要素に置かれた最初 (唯一) の要素であるtextbox
要素への参照が取得されます。そのvalue
プロパティが取得されることで、テキスト入力欄のテキストが取得されます。続いて、この値をclipboard
フィールドに代入します。これによって、テキスト入力欄のテキストが、この専用のクリップボードにコピーされることになります。 -
document.getAnonymousNodes(this)[0].value=''
次に、textbox
のテキストとして空の文字列を代入します。これは、テキスト入力欄の テキストをクリアする効果があります。
また、コピー操作も同様ですが、処理後、テキストをクリアしない点が異なります。 貼り付け操作は逆の処理、 つまりテキスト入力欄の値に、clipboard
フィールドの値を代入する操作が行われます。 なお、実用レベルで、こうしたクリップボードのキーボードショートカットを実装する場合には、 本物のクリップボードインタフェースを利用するとともに、選択中のテキストのみが処理されるようにする必要があるはずです。
次のセクションでは、既存の XBL 定義を拡張する方法について見ていきます。