Proto.Menuを使って、右クリックメニューをカスタマイズする
Proto.Menuは右クリックメニューを自分で好きなようにカスタマイズできるJSライブラリです。
実際にはコンテキストメニュー自体を編集するわけではなく、右クリック時のデフォルト・イベントを停止して、
代わりにHTML要素で作成したメニューを見かけ上、コンテキストメニューのように表示しているだけです。
しかし、手軽に右クリックメニューを自分仕様にできるため、扱い方によってはサイトのユーザビリティ改善に
役立つと思います。WIZ-CODE.blogにあるBGMプレーヤーもProto.Menuを使用しています。
ただし、Operaなど一部のブラウザではまったく対応していないか、バージョンによって対応していないものもあるので、
あくまで補助的な用途に使うのがよさそうです。
また、Proto.Menuは毎度ながらPrototypeに依存しているため、使用する場合はPrototypeを読み込む必要があるます。IE8対策
の最新版をダウンロードしてください。
Prototypeはここから、
ProtoMenuはこのページからダウンロードできます。
 
ProtoMenuに関しては、JavaScriptファイル
とCSSファイルがそれぞれ必要になります。
準備すること
PrototypeとProto.Menu、Proto.MenuのCSSファイルをアップロードし、 HTMLのheadタグ内に二つのJSファイルと、proto.menuのCSSファイルを記述します。
メニュー内容を編集する
メニュー項目をJSON形式でまとめる
メニューの内容はJavaScriptで以下のように記述します。
このようにmyMenuItemsという配列(配列名は任意)に、中カッコ{}でくくられたオブジェクトに各メニューを追加していきます。 まずメニューの表示名、たとえば「編集」、「コピー」などを"name"プロパティに設定します。個別にCSSを適用したい場合は "className"プロパティにクラス名を入れます。ただ、メニュー全体のデザインは別途設定するので、これを利用するのは、 メニュー名の左側に小さいアイコンをつけたいときなどです。"disabled"プロパティをtrueにすると、そのメニュー名の フォント色がグレーに変わり、クリックしても反応しなくなります。メニューの見出しに使うのがいいでしょう。"separator" プロパティをtrueにすると、メニューリストを区切る線が入ります。なお、同メニューのオブジェクトには"separator"以外のプロパティは 追加しません。"callback"プロパティは、このメニューがクリックされた際に呼び出す関数を記述します。
Proto.Menuを初期化する
Proto.Menuを機能させるには、new演算子でProto.Menuクラスを呼び出します。このスクリプトは画面のロード終了後に 呼び出す必要があります。
"selector"には文字通りCSSのセレクタを指定します。たとえば"my_menu"というID名の要素をクリックした際、
メニューを表示させたいなら、"#my_menu"とします。"wiz_menu"というクラス名の要素すべてに適用したいならば、
".wiz_menu"とし、その他、すべてPタグ要素に適用するなら"p"、ページ全体に適用したいなら"body"などとします。
次に"className"ですが、ここでメニュー全体のデザインを決めます。デフォルトでは三タイプのデザインが用意してあり、
それぞれdesktop,firefox,googleのなかから選ぶことができます。もちろん自分自身でデザインすることも可能です。
これらのデザインに加えて、共通デザインとなる"menu"を追加して記述してください。"menuItems"プロパティには先ほど
編集した配列を入れます。
必須となるのは上記の三項目ですが、その他にいくつか設定できるプロパティがあります。"fade"プロパティをtrueにすると、
メニューが表示される際にフェード効果がかかります。デフォルトではfalseです。ただし、エフェクトにscript.aculo.usを利用しているため、effects.jsが
インクルードされていなければなりません。また、z-indexは初期設定で100となっていますが、"zIndex"プロパティで変更可能です。
また、コールバック関数として"beforeShow"、"beforeHide"、"beforeSelect"の設定ができます。"beforeShow"は右クリック
された直後に、"beforeHide"はメニューが隠れた直後に呼び出されます。これらは第一引数にメニューリスト要素のイベント・オブジェクト
が渡されます。一方、"beforeSelect"は各メニュー項目がクリックされたときに呼び出されます。第一引数はクリックされた各メニュー要素
のイベント・オブジェクトです。"beforeSelect"コールバックは前述のBGMプレイヤーで使われており、後ほど使用例を解説します。
メニューリスト用のタグを配置
メニューリスト用の要素を忘れていましたね。HTML上の任意の場所に、"selector" プロパティに指定したセレクタ(要素名やID属性、クラス名など)の要素を配置します。この要素を右クリックしたときに メニュー表示されます。
"beforeSelect"コールバックの使い道
リストの数だけ異なるコールバック関数をわざわざ書くのは面倒です。もしそれぞれのメニューのコールバックが、同じような処理をする内容 ならば、"beforeSelect"コールバックを使って簡略化することができます。
上記のメニューには、クリックするとそのメニュー名をアラートするコールバックが設定されています。しかし、コールバックのコードはそれぞれ 微妙に違います。リスト数がこのくらいならいいですが、もっと多くのリストを扱うならば編集や修正が面倒になります。 そこで、先ほどの"beforeSelect"コールバックを使って、クリックした要素のメニュー名を取得するスクリプトを書いてみます。
メニュー名は変数selectedNameに格納されるので、各メニューのコールバックを統一できました。
メニューデザインのカスタマイズ
メニューのデザインをカスタマイズしたい場合、proto.menu.cssを開きます。デフォルトのままでも十分ではありますが、 設定を修正したほうがいい箇所がいくつかあります。
フォントファミリーはデフォルトでverdanaのみになっています。メニュー名が英数字のみなら十分ですが日本語にするなら、 日本語フォントを追加しておくほうが親切です。下の例はフォントを「メイリオ」優先にしています。
また、フォントサイズはデフォルトで11pxと、やや小さめになっているので、変更する場合は次の個所を修正します。
メニュー要素の幅の変更は各デザインのCSSを修正する必要があります。ここでは、"desktop"デザインを使って変更箇所を見ていきます。 設定するセレクタは大きく分けて6つあり、これはfirefoxやgoogleデザインでも変わりません。オリジナルデザインを作るときは、これらの スタイルをコピペして使うといいでしょう。
よく見ると"desktop"デザインではマウスオーバー時の設定がないですね。マウスを合わせた際の背景色を設定する場合は、次のコードを追加します。
オリジナル・メニューのサンプル
サンプルとしてオリジナル・メニューを作ってみたので、参考にしてください。