メニュー
メニューはユーザが実行できるコマンドの一覧を提供します。
メニューの種類
メニューは menupopup
タグを使って作成します。メニューは一般にメニューバーかボタンに取り付けられます。メニューかボタンがクリックされるとメニューが開かれ、利用できるコマンドが一覧表示されます。ユーザはコマンドを選んで実行したり、 Esc キーを押すかメニューの外側をクリックする事で操作をキャンセルすることができます。
XUL にはメニューを作成するためのタグがいくつか用意されています。それらのタグを使って、メニューをメニューバー上に設置したり、ボタンに取り付けることが出来ます。また、メニューをメニューの中に入れ子にすることによってサブメニューが作成できます。メニューやサブメニューを開いたり閉じたりするのに特別なコードを書く必要は無く、メニューはスクリーン上の適切な位置に自動的に設置されます。
menupopup を取り付けられる要素には 4 種類のものがあります。どの場合でも、menupopup 要素はその要素の直接の子として設置します。以下にそれらの要素の概要を示します。それぞれの詳しい例は後ほどお見せします。
- menu
- menu タグはメニューバーにメニューを設置する時に使用します。アプリケーションウィンドウの上端 (またはスクリーン上部のメニューバー) にある「ファイル」や「編集」などがメニューの例です。この種類のメニューは普通、アプリケーション全体に対して適用するコマンドのために使われます。その時点で適用できないコマンドは無効にするべきですが、実際のトップレベルメニューはほとんどの場合ウィンドウによって変化することはありません。
- button
- ボタンの
type
属性を「menu」にすると、メニューをボタンに取り付けることが出来ます。こうすると、普通のボタンではなく小さな矢印やその他のインジケータの付いたボタンが作成されます。ボタンをクリックするとメニューが表示され、コマンドを選択できます。この種類のメニューは、一連のコマンドを提供したいけれどメニューバーを使いたくない場合、例えばダイアログボックスなどでよく使用されます。詳しくはメニューボタンを参照して下さい。 - toolbarbutton
- ツールバーボタンもメニューをサポートしています。これは他のボタンと同じように動作します。詳細はメニューボタンを参照して下さい。
- menulist
- menulist はユーザに一覧の中からアイテムを選択させたい時に使用します。この種類のメニューでは、その中のアイテムのうちの一つが選択されます。他のアイテムが選択されると、そのアイテムのラベルが menulist のラベルとして設定されます。他のユーザインターフェイスではこの種のウィジェットはコンボボックスと呼ばれています。
menupopup タグの代わりに popup タグが使用されているのを見かける事があるかもしれません。 popup タグは非推奨ですが、menupopup タグと同等のものです。
メニュー用タグの概要
以下は「File」というラベルの付けられたメニューを一つだけ持つ簡単なメニューバーの例です。
<menubar id="sample-menubar"> <menu id="file-menu" label="File"> <menupopup id="file-popup"> <menuitem label="New"/> <menuitem label="Open"/> <menuitem label="Save"/> <menuseparator/> <menuitem label="Exit"/> </menupopup> </menu> </menubar>
この例では 5 つのタグが使われています。簡単に説明します。
- menubar
- ウィンドウまたはスクリーンの上端に表示されるメニューの列です。この中には menu 要素を格納するべきです。
- menu
- 「File」や「Tools」などの、メニューバー上のメニューのラベルです。メニューはサブメニューのラベルとしても使用されます。
- menupopup
- メニュー上に表示されるアイテムを格納したポップアップです。上の例の menupopup は「File」メニューの子で、メニューのラベルがクリックされると表示されます。
- menuitem
- メニュー上に表示される個々のアイテムです。ユーザがマウスを menuitem の上に移動すると、アイテムがハイライトされます。カーソルキーを使っても選択中のアイテムを変更できます。 menuitem は実行するコマンドと関連付けられます。
- menuseparator
- メニューのアイテムの間の区切りです。
上の例では、「File」メニューには 4 つの menuitem と 1 つの menuseparator があります。menu と menuitem はそれぞれその目的を表すラベルを持っています。
他の種類のタグを menupopup 上に表示させる事は出来ません。メニューとは違う多目的のポップアップを作成したければ、panel を使用してください。詳しくは パネル を参照して下さい。
menubar 要素
メニューバーは XUL の menubar タグを使って作成します。通常は、メニューバーはアプリケーションのメインウィンドウの上部を横切るように配置されます。Macintosh では、メニューバーはスクリーンの上端に配置されます。この違いに対処するのに何か特別な事をする必要はありません。XUL ウィンドウがパースされる時、最初に見つかった menubar がそのウィンドウのメインメニューバーとして使用され、Macintosh ではそれがメインウィンドウから隠されてスクリーン上部のネイティブメニューに変換されます。このため、ウィンドウはメニューバーを 1 つだけ持つべきですが、それぞれのウィンドウが違うメニューバーを持つことは可能です。
menubar の中には menu 要素をそれぞれのメニューに対して 1 つ置きます。下は 3 つのメニューを持つメニューバーの例です。
<menubar id="sample-menubar"> <menu id="file-menu" label="File"> ... </menu> <menu id="tools-menu" label="Tools"> ... </menu> <menu id="help-menu" label="Help"> ... </menu> </menubar>
menubar に他の要素を置く事も可能ですが、それらは Macintosh では表示されないという事を覚えておいてください。そのため、その要素の機能を他の場所で使用できないか確かめるべきです。もしくは、複数のプラットフォームで異なる方法をとるようなコードを書いてください。menubar に他の要素を設置する時に、それを他のメニューの隣ではなく反対側におきたい事があるかもしれません。これは伸び縮みする spacer を置く事で可能になります。
<menubar id="sample-menubar"> <menu id="file-menu" label="File"> ... </menu> <spacer flex="1"/> <image src="logo.png"/> </menubar>
この例では、ロゴ画像がメニューバーの端に設置されます。
menupopup 要素
menupopup 要素は、メニューアイテムを表示するポップアップです。menubar のメニューに対して使う時は、menupopup を menu 要素の子要素として設置します。以下は簡単なヘルプメニューの例です。
<menu label="Help"> <menupopup> <menuitem label="Contents"/> <menuitem label="Search Help"/> </menupopup> </menu>
通常は、menupopup は隠されています。「Help」ラベルが押されると、menupopup がウィンドウの上端に、Help メニューのラベルの底辺に揃えて表示されます。メニューコマンドが選択されるかメニューがキャンセルされると、menupopup は再びスクリーンに表示されなくなります。
menu 要素
menu 要素は menubar 上のラベルやサブメニューのラベルに使われます。サブメニューについての情報は、下のサブメニューを参照して下さい。
menu 要素のラベルは label
属性を使って指定します。下の例では、メニューに「View」というラベルが付けられています。
<menu label="View"> <menupopup> <menuitem label="Toolbar"/> <menuitem label="Status Bar"/> </menupopup> </menu>
メニューがクリックされると、メニューはその中に格納された menupopup を開きます。このため、menupopup は menu の直接の子として設置するようにして下さい。
メニューはキーボードを使っても開く事ができます。ユーザは特定のキーを押してメニューのラベルをハイライトさせて、カーソルキーを使ってメニュー間を移動します。このキーはプラットフォーム毎に異なり、例えば Windows では F10 キーが使われます。メニューコマンドに簡単にアクセスできるようにするもう一つの方法として、それぞれの menu 要素にアクセスキーと呼ばれるショートカットキーを追加する方法があります。いくつかのプラットフォームでは、アクセスキーを追加すると、どのキーを押せばいいのかを示すためにメニューのラベルの中の一文字に下線が引かれます。このため、アクセスキーは必ずメニューのラベルに表示される文字のどれかと一致させるべきです。
メニューに対してアクセスキーを設定するには、下の例のように accesskey
属性を使います。
<menu label="File" accesskey="F"/>
このメニューは (一般的には Alt キーと同時に) アクセスキーを押すことで開く事が出来ます。
当然のことながら、アクセスキーは menubar の中で一意のものであるべきです。よってもし「Find」というラベルのメニューを追加したければ、違うアクセスキーを設定する必要があるでしょう。
<menubar> <menu label="File" accesskey="F"/> <menu label="Find" accesskey="d"/> </menubar>
この例では、「File」メニューのアクセスキーが「F」に、「Find」メニューのアクセスキーが「d」に設定されています。アクセスキーは大文字と小文字を区別しませんが、大文字小文字が一致するものがあれば必ずそちらに下線が引かれます。例えば、アクセスキー「W」は「Window」というメニューラベルの最初の文字にマッチしますが、アクセスキー「w」は最後の文字にマッチします。アクセスキーを設定する時には常に大文字小文字を一致させた方がいいでしょう。
menuitem 要素
menuitem 要素はメニューのポップアップ上に現れる個々のアイテムに使われます。menu 要素と同様に、 label
属性と accesskey
属性を使ってアイテムに対してラベルとアクセスキーを設定できます。
<menuitem label="Open" accesskey="O"/>
menuitem のアクセスキーはそれが格納されているメニューが開かれている間しか機能しないので、アクセスキーはそのメニューの中でのみ一意のものであれば良いという事になります。
メニューが開かれている間にアイテムがマウスでクリックされるかアクセスキーが押されると、menuitem で command イベントが発生します。これを利用して、menuitem に特定の動作を関連付ける事が出来ます。例えば「Open」メニューアイテムに、開くファイルを選択するためのファイルピッカーを開く動作を関連付けたり出来ます。この例では、 oncommand
属性を使って command イベントリスナをアイテムに取り付けています。ここではただ単に警告メッセージを開くだけにしています。
<menuitem label="Open" accesskey="O" oncommand="alert('Open a File!');"/>
メニューアイテムに動作を関連付けるには、 command 要素を使う方法もあります。下の例は先ほどの例と同じ効果がありますが、command イベントを直接とらえる代わりに command 要素を使っています。
<command id="cmd_open" oncommand="alert('Open a File!');"/> ... <menuitem label="Open" accesskey="O" command="cmd_open"/>
command
属性には同じドキュメント内にあるコマンド要素の id を設定します。この場合は「cmd_open」です。こうすると、command イベントは menuitem ではなく command 要素で発生します。これは例えばメニューバーのメニューアイテムや、コンテキストメニュー、ツールバーボタンなどのいくつかの要素に同じ動作を実行させたい時に便利です。それぞれの要素に command を結びつければ、実行するコードを command 要素に一度設置するだけで済むからです。
menuitem には、ラベルの横にアイコンや関連付けられたショートカットを表示させる事も出来ます。メニューにショートカットキーを追加する方法の詳細はメニューアイテムにショートカットキーを追加するを参照して下さい。また、メニューにアイコンを追加する方法はメニューアイテムにアイコンを追加するを参照して下さい。
チェックボックス型のメニューアイテムやラジオボタン型のメニューアイテムを作成する方法は チェックボックス型メニューアイテム もしくは ラジオボタン型メニューアイテムを参照して下さい。
メニューアイテムは disabled
属性を true にする事で無効にすることが出来ます。この例はメニューアイテムの無効化を参照して下さい。
menuseparator 要素
menuseparator 要素を使うとメニューの間に区切りを作成する事が出来ます。メニューの中で関連性のあるコマンドは一つにまとめ、異なるグループの間には区切りを入れるのがいいでしょう。そうするとメニュー上のアイテムを見分けるのが簡単になります。menuseparator に使用できる特別な属性はありません。
<menuseparator/>
サブメニュー
メニュー上のアイテムに、それが選択された時にのみ開かれるもう一つのメニューにしまい込まれた追加のコマンドを持たせたい事があるでしょう。menu 要素を他の menupopup の中に入れ子にすると、サブメニューを作成できます。マウスがサブメニューのラベルの上に移動するか、カーソルキーでサブメニューを選択すると、そのメニューのポップアップが表示されます。マウスが離れるか選択アイテムが変更されると、メニューは閉じられます。
<menubar id="sample-menubar"> <menu id="view-menu" label="View"> <menupopup> <menuitem label="Toolbar"/> <menuitem label="Status Bar"/> <menuseparator/> <menu label="Sort" accesskey="S"> <menupopup> <menuitem label="By Name"/> <menuitem label="By Date"/> </menupopup> </menu> </menupopup> </menu> </menubar>
この例では、トップレベルの「View」メニューが 2 つのメニューアイテムと、 1 つの区切り線と、menu タグで作成された 1 つのサブメニューを持っています。このメニューは「Sort」というラベルとアクセスキー「S」を持っています。また、このメニューは 2 つのアイテムを持つ menupopup を子に持っています。この menupopup の構文は外側の menupopup と同じものです。
さらに、「Sort」menupopup の中のアイテムとしてもう一つ menu 要素を使用すれば、 3 段階目のメニューを追加する事も出来ます。ですが、そうするとユーザにとっての使用が難しいものになってしまいがちなので、あまり深いレベルのサブメニューは追加しない方がいいでしょう。
ウィンドウ間でメニューを共有する
いくつかのウィンドウで同じメニューバーを共有したければ、メニューバーをオーバーレイに設置してそれを全てのウィンドウに適用するというのが一般的な手法です。こうするとコードが重複することなくそれぞれのウィンドウにメニューバーを共有させる事が出来ます。例えば、 Tools メニューを全てのウィンドウで共有させたければ、メニューをオーバーレイの中に作成し、それぞれのウィンドウには一行だけ書いてそのメニューを追加します。
<menu id="menu-tools"/>
オーバーレイには、そのメニューの内容が完全に記述された、同じ「menu-tools」という id を持つ menu
を設置してください。
もしウィンドウ間でちょっとした違いを持たせたければ、load イベントリスナでメニューアイテムを表示したり隠したりするのもいいでしょう。例えば、ウィンドウが開かれる時にアイテムを非表示にしたければこのようにします。
function initMenus() { var item = document.getElementById("menu-file-open"); item.hidden = true; }
「menu-fileOpen」という id を持つメニューを隠すために hidden
プロパティが true に設定されています。この関数は window の onload
属性の中で呼び出すことが出来ます。