MenuItems

menuitem 要素は単にメニューコマンドのラベルであるだけではなく、さまざまな機能を持っています。

ショートカットキーの追加

メニューアイテムにはショートカットキーを関連付けることができます。メニューが開かれている間しか機能しないアクセスキーとは違い、ショートカットキーはどんな時でも機能します。ショートカットキーを作成するには、key 要素を使います。実際にキーボードショートカットを処理するのは key 要素ですが、ショートカットはメニューアイテムのラベルの横に表示されます。これにより、ユーザーはメニューを見ることで、利用できるショートカットキーを知ることができます。

<keyset>
  <key id="open-key" modifiers="accel" key="O" />
  <key id="close-key" modifiers="accel" key="C" />
</keyset>
<menubar>
  <menu label="View">
    <menupopup>
      <menuitem label="Open" key="open-key" />
      <menuitem label="Close" key="close-key" />
    </menupopup>
  </menu>
</menubar>

Image:Popupguide-menushortcut.png

key 属性によって、2 つのメニューアイテムにショートカットキーが関連付けられています。key 属性は同じドキュメント内の key 要素の id に設定しなければなりません。このようにすると、メニューアイテムのラベルの横にショートカットキーが表示されます。この例の "Open" アイテムは、"accel" 修飾キーを押しながら "O" キーを押すことで実行できます。"accel" 修飾キーはプラットフォームによって異なりますが、ショートカットキーで一般的に使用されるキーになります。たとえば、accel キーが Control キーならば、メニューには "Ctrl + O" と表示されるでしょう。

普通はやる必要はありませんが、acceltext 属性を使うと、メニューに表示されるキーボードショートカットのラベルをカスタマイズすることができます。これはたとえば、現在開かれているウィンドウの一覧を表示するメニューなど、アイテムに関連付けられるキーが変化するような場合に使用するのがいいでしょう。

<menuitem label="First Window" acceltext="1" />

こうするとキーボードショートカットのラベルが "1" になりますが、そのキーを処理するコードも書く必要があります。

アイコンの追加

image 属性を使うと、メニューアイテムにアイコンを追加できます。アイコンはメニューアイテムのラベルの左に表示されます。アイコンが表示されるようにするためには、image 属性に加えて、"menuitem-iconic" という特殊なクラスを設定しなければなりません。

<menuitem id="add-bookmark" class="menuitem-iconic" label="Add Bookmark" image="addbookmark.png" />

アイコン画像はメニューアイテム上に表示されるので、かなり小さい画像を使用しなければなりません。メニューアイテムの画像のサイズは、厳密には使用されているテーマによって異なりますが、一般的には 16 x 16 pixel 前後にするべきです。image 属性を使ってアイコンを指定する代わりに、スタイルシートで "list-style-image" プロパティを使って画像を参照することもできます。

#add-bookmark {
  list-style-image: url('addbookmark.png');
}

この手法は menu 要素に対して画像を適用するのにも使用できますが、その場合クラス名には "menu-iconic" を指定しなければなりません。

<menuitem id="bookmark" class="menu-iconic" label="Bookmarks" image="bookmarks.png" />

チェックボックス型メニューアイテム

トグル式の動作をするメニューアイテムを使用したい場合があるでしょう。たとえば、ツールバーの表示非表示を切り替えるメニューアイテムなどです。このメニューアイテムには、ツールバーの現在の状態を示すために、ラベルの隣にチェックボックスが表示されます。チェックボックスがオンならばツールバーは表示されており、オフならば表示されていません。ユーザーはメニューアイテムを選択する事でツールバーの表示を切り替えることができます。

このような種類のメニューアイテムは、type 属性を "checkbox" という値に設定すると作成できます。

<menu label="View" accesskey="V">
  <menupopup>
    <menuitem label="Show Toolbar" accesskey="T" type="checkbox" checked="true" />
    <menuitem label="Show Status Bar" accesskey="S" type="checkbox" />
  </menupopup>
</menu>

Image:Popupguide-menucheckbox.png

2 つあるメニューアイテムが共にチェックボックス型になっています。1 つめのメニューアイテムは checked 属性が true に設定されているので、デフォルトでチェックされています。2 つめのメニューアイテムはデフォルトではチェックされていません。ユーザーがメニューアイテムを選択すると command イベントが発生するので、ツールバーやステータスバーなどの状態を変化させるコードを command イベントリスナから実行することができます。メニューアイテムの checked 属性は command イベントが発生する前に自動的に更新されるので、自分で属性値を更新する必要はありません。

チェック状態は command イベントが発生する前に更新されるので、command イベントリスナ内でメニューアイテムの checked 属性を使用する場合には、チェック状態はすでに新しい状態にあるということに注意してください。

<script>
function changeToolbarState(event) {
  if (event.target.getAttribute("checked") == "true")
    showToolbar();
  else
    hideToolbar();
}
</script>
...
<menuitem label="Show Toolbar" accesskey="T" type="checkbox"
          oncommand="changeToolbarState();"/>

この例では、メニューアイテムがチェックされているとツールバーを表示し、チェックされていなければツールバーを隠します。

メニューアイテムが選択された時に、チェックボックスの状態を自動的に更新して欲しくない場合があるかもしれません。これは実行される動作が失敗する可能性がある場合に有効です。単純にチェックボックスの状態を元に戻すというやり方もありますが、余計にややこしくなる可能性があります。 autocheck 属性を使うと、チェックボックスが自動的に更新されないようにできます。autocheck 属性を false に設定すると、チェックボックスの状態は自動的に更新されなくなるので、チェック状態を変更するコードを自分で書かなければなりません。

<script>
function changeToolbarState(event) {
  if (event.target.getAttribute("checked") == "true")
    hideToolbar();
    event.target.removeAttribute("checked");
  } else {
    if (!showToolbar())
      return;
    event.target.setAttribute("checked", "true");
  }
}
</script>
...
<menuitem
 label="Show Toolbar"
 accesskey="T"
 type="checkbox"
 autocheck="false"
 oncommand="changeToolbarState();" />

このバージョンの changeToolbarState 関数は checked 属性を自分で変更します。メニューアイテムの autocheck 属性が false に設定されているので、checked 属性は自動的に更新されません。コードの条件ブロック部分が入れ替えられていることに注目してください。メニューアイテムがチェックされていたらツールバーを隠し、チェックされていなければツールバーを表示するようになっています。これはあらかじめチェック状態が変更されないからです。この例では関数 showToolbar が失敗する可能性を想定しており、もし false が返されたら checked 属性は変更されません。

チェック状態を解除する時には、checked 属性を単に false に設定するのではなく、属性自体を取り除くようにしてください。この例では removeAttribute メソッドによって属性を削除しています。

ラジオ型メニューアイテム

一度に一つしかチェックできないようなメニューアイテムのグループを作成したい場合には、ラジオ型のメニューアイテムを使用します。ラジオ型はチェックボックス型と似たような動作をしますが、あるアイテムが選択されると、同じグループにある他のアイテムはすべてチェックが外される点が異なります。ラジオ型のメニューアイテムのチェック状態は、チェックボックス型と同様に自動的に更新されるので、自分で更新する必要はありません。

ラジオボタンのように動作するメニューアイテムを作成するには、type 属性を "radio" に設定します。それに加えて、name 属性を、メニューアイテムが属するグループの名前に設定します。name 属性の値はどんな名前にしてもかまいませんが、同じメニュー内にあり、同じ名前を持つメニューアイテムは、すべて同じグループに属することになります。

<menu label="Sort" accesskey="S">
  <menupopup>
    <menuitem label="By Name" accesskey="N" type="radio" name="sort" />
    <menuitem label="By Date" accesskey="D" type="radio" name="sort" checked="true" />
    <menuitem label="By Subject" accesskey="S" type="radio" name="sort" />
    <menuseparator/>
    <menuitem label="Ascending" accesskey="A" type="radio" name="order" checked="true" />
    <menuitem label="Descending" accesskey="c" type="radio" name="order" />
  </menupopup>
</menu>

Image:Popupguide-menuradio.png

このメニューでは、 3 つのラジオ型メニューアイテムがすべて "sort" という同じ名前を持っています。そのため、それらのうち 1 つのアイテムを選択すると、そのアイテムがチェックされ、同じグループの他のアイテムはすべてチェックが外されます。最後の 2 つのメニューアイテムは "order" という違うグループに属しています。一方を選択するともう一方のチェックが外されますが、他のグループに属するアイテムには影響を及ぼしません。

それぞれのグループのうち 1 つのアイテムで、checked 属性が true に設定されていることに注目してください。これがメニューのデフォルトの値になります。この値が設定されていなければ、デフォルトではグループ内のどのアイテムもチェックされません。

チェックボックス型のメニューアイテムと同様に、autocheck 属性を使って、チェック状態の自動変更を無効にすることができます。この属性はそれぞれのラジオ型メニューアイテムに対して設定する必要があります。

メニューアイテムの無効化

アイテムを初期状態で無効にするには、次の例のように disabled 属性を true に設定します。

<menuitem label="Undo" accesskey="U" disabled="true" />

無効化されると、アイテムはグレーアウトして表示され、関連付けられた動作は実行できなくなります。アイテムが無効化されていると、command イベントは発生しません。適切でないメニューアイテムを無効にするには、disabled プロパティを true に設定します。アイテムをふたたび有効にするには、disabled プロパティを false に設定します。無効状態の変更は、popupshowing イベント内で行うのがいいでしょう。popupshowing イベントの詳細は popupshowing イベントの節を参照して下さい。

メニューアイテムにコマンドが関連付けられている場合には、コマンドを無効にすることでメニューアイテムを無効にすることができます。たとえば下の例では、disabled 属性によって "Delete" コマンドが無効化されています。

<command id="cmd_delete" disabled="true" oncommand="alert('Deleted!');" />
<menuitem label="Delete" accesskey="F" command="cmd_deleted" />

メニューアイテムがコマンドに結びつけられているため、コマンドが無効化されるとメニューアイテムも無効化されます。コマンドの無効状態が変化すると、それに従ってメニューアイテムの無効状態も更新されます。これは同じコマンドにいくつかのメニューアイテムやボタンを結び付けている場合に役立ちます。コマンドの無効状態を一度変更するだけで、そのコマンドに結び付けられたすべての要素に無効状態が反映されるからです。

メニューアイテムの変更

メニューアイテムのラベルとアクセスキーは、スクリプトから label プロパティと accessKey プロパティを変更する事で動的に変更できます。accessKey というプロパティ名では小文字と大文字が使われているのに対して、XUL の accesskey という属性名は小文字のみが使われていることに注意してください。

たとえば、"Undo" メニューアイテムのラベルを、何を元に戻すかによって変更したいことがあるかもしれません。下の例でこれを実践しています。

if (gUndoBufferType == "typing") {
  menuitem.label = "Undo Typing";
} else if (gUndoBufferType == "paste") {
  menuitem.label = "Undo Paste";
} else {
  menuitem.label = "Undo";
}

メニューにアイテムを追加したり削除する方法の例は、メニューの変更を参照して下さい。

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

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