使いやすい右クリックメニューを作りたいな。
こんにちは。HTMLやJavaScriptの開発歴8年の著者が、JavaScriptを使ったオリジナルの右クリックメニューの表示方法をご紹介します。
例えばWebアプリなどで右クリックした時、オリジナルのメニューが表示されてたくさんの便利な機能が使えたら、素晴らしいと思いませんか?そのような右クリックメニューがあると、ユーザーインターフェースは劇的に向上するでしょう。
JavaScriptを使えば、それが実現できるのです!では早速、簡単な例を交えて右クリックメニューの実装方法について解説していきたいと思います。
JavaScriptで右クリックメニューの要素を扱うには
JavaScriptで右クリックメニューを作るために、まずはHTMLとスタイルシートを使って基本的な画面の要素を作成しておく必要があります。それでは簡単な例を作成してみましょう。
HTMLの例
HTMLとしてこのような画面を作ります。
<html> <head> --省略-- </head> <body> <div id="contextmenu"> <ul> <li>menu1</li> <li>menu2</li> <li>menu3</li> </ul> </div> </body> </html>
これをそのままブラウザで表示すると、このようになります。
非常にシンプルに、bodyの中に右クリックメニュー用の要素を作っています。<div id="contextmenu">で囲まれた範囲が右クリックした時に表示してほしいメニューです。
しかしこのままでは右クリックする前にメニューが表示されたままですので、事前に隠しておく必要があります。
スタイルシートの例
メニューはスタイルシートを使って隠しておくことができます。headタグの中に、このように書いてみましょう。
<head> --省略-- <style> #contextmenu{ display:none; position:fixed; left:0px; top:0px; width:200px; height:100px; border:1px solid #000; background-color:#fff; } #contextmenu li{ cursor:pointer; } </style> </head>
右クリックメニューの要素(#contextmenu)をdisplay:noneにして非表示にしておきます。これで、とりあえず画面には何も表示されない状態になりました。
そして大事なことが、position:fixed;と書くことです。こう書くと、この要素を他の要素の上に覆いかぶさるような形で表示できるため、右クリックメニューをマウスの位置に合わせて表示することができるようになります。
また、座標はleftとtopという値を設定することで指定できます。最初はどちらも0pxで、これは画面の一番左上に位置させるということになります。
HTMLとスタイルシートの書き方は以上です。それでは次にJavaScriptで右クリックメニューを表示するイベントを作っていきましょう。
JavaScriptで右クリック時のイベントを作成しよう
まずはJavaScriptで右クリック時のイベントを取得する必要があります。さっそく、コードを書いてみましょう。
JavaScriptで右クリックイベントを追加する
先ほど書いたスタイルシートの後に、次のように記述するとJavaScriptで右クリックイベントを取得できます。
<head> --省略-- <style> --スタイルシートの設定-- </style> <script> window.onload = function(){ document.body.addEventListener('contextmenu',function(e){ }); } </script> </head> <body onContextmenu="return false;"> --省略-- </body>
右クリック時の処理を追加するには、addEventListenerを使います。このaddEventListenerは、ユーザー操作による処理を追加する時に使用されるもので、今回はbody要素で右クリック、つまりcontextmenuというイベントが発生したときに、この中に書かれた処理が実行されるようになります。
また、bodyタグにonContextmenu="return false;"を追加することで、既存の右クリックの処理をキャンセルすることができます。
メニューを表示する
それでは処理内容を書いてみましょう。まずはメニューを表示します。
<head> --省略-- <style> --スタイルシートの設定-- </style> <script> window.onload = function(){ document.body.addEventListener('contextmenu',function (e){ document.getElementById('contextmenu').style.display="block"; }); } </script> </head>
これで、画面上で右クリックするとこのように表示されるようになりました。
getElementById(‘contextmenu’)でメニュー要素を取得し、その後のstyle.display=”block”でメニュー要素のスタイルを非表示から表示に変更しています。しかし、これではメニューは左上に表示されただけです。
ですので、右クリックメニューをマウス位置に表示できるよう一手間加えたいと思います。
メニューをマウスの位置へ移動する
次のようにコードを追加することで、メニューの表示位置をマウス位置まで移動させることができます。
<head> --省略-- <style> --スタイルシートの設定-- </style> <script> window.onload = function(){ document.body.addEventListener('contextmenu',function(e){ document.getElementById('contextmenu').style.left=e.pageX+"px"; document.getElementById('contextmenu').style.top=e.pageY+"px"; document.getElementById('contextmenu').style.display="block"; }); } </script> </head>
これを実行すると、このようになります。
ちゃんとマウスの位置にメニューが表示されていますね!具体的にどのようにしているかと言うと、e.pageXとe.pageYでマウスの位置を取得して、それをメニュー要素のleftとtopの値に設定することで、メニューをマウスの位置へ移動させています。
ところで、addEventListenerの中にfunction(e)と書かれていますが、このeとはいったい何でしょうか?これはMouseEventというオブジェクトで、マウス操作をした時の様々な情報が集約されたものです。
そのため、e.pageXとe.pageYでマウスの座標が取得できたのです。このeは色々な使い方ができますので、覚えておくと良いでしょう。
メニューが選択された時の動作を作成しよう
次に、右クリックメニューの中の項目がクリックされた時の動作を作成します。
メニューの要素にonClickイベントを追加する
メニューの項目それぞれにonClickのイベントハンドラを追加します。
<li onClick="menu1()">menu1</li> <li onClick="menu2()">menu2</li> <li onClick="menu3()">menu3</li>
こうすることで、各メニューに対してそれぞれ別の処理を作成することができます。
JavaScriptに処理内容を追加する
メニュー項目をクリックしたときに呼び出される関数を、次のように書きます。
<script> window.onload = function(){ document.body.addEventListener('contextmenu',function (e){ document.getElementById('contextmenu').style.left=e.pageX+"px"; document.getElementById('contextmenu').style.top=e.pageY+"px"; document.getElementById('contextmenu').style.display="block"; }); } function menu1(){ alert("menu1がクリックされました。"); } function menu2(){ alert("menu2がクリックされました。"); } function menu3(){ alert("menu3がクリックされました。"); } </script>
このようにして、menu1、menu2、menu3のそれぞれに対して別のメッセージを表示することができるようになります。
今回は簡単にメッセージ表示だけでしたが、この処理を充実させることで、様々な内容の右クリックメニューを作成することができます。
メニューを閉じる動作を作成しよう
最後に右クリックメニューを閉じる動作を作成します。右クリックメニュー以外のエリアをクリックするとメニューが閉じるようにしていきましょう。
body要素でのクリックイベントを追加する
右クリックメニュー以外をクリックしたときのイベントを取得したいのですが、どの要素にクリックイベントを追加するのが良いでしょうか。それはbody要素に対してです。
body要素に対して追加することで、右クリックメニュー以外のエリアをクリックしたときにイベントを発生させることができます。
window.onload = function(){ document.body.addEventListener('contextmenu',function (e){ document.getElementById('contextmenu').style.left=e.pageX+"px"; document.getElementById('contextmenu').style.top=e.pageY+"px"; document.getElementById('contextmenu').style.display="block"; }); document.body.addEventListener('click',function (e){ document.getElementById('contextmenu').style.display="none"; }); }
このように、addEventListenerでclickイベントを取得して、contextmenuのdisplayスタイルをnoneに変更しています。これで右クリックメニューを非表示にすることができます。
以上でJavaScriptを使ったオリジナルの右クリックメニューを実装することができました。今回の作成したコード全体をまとめてみましょう。
<html> <head> --省略-- <style> #contextmenu{ display:none; position:fixed; left:0px; top:0px; width:200px; height:100px; border:1px solid #000; background-color:#fff; } #contextmenu li{ cursor:pointer; } </style> <script> window.onload = function(){ document.body.addEventListener('contextmenu',function (e){ document.getElementById('contextmenu').style.left=e.pageX+"px"; document.getElementById('contextmenu').style.top=e.pageY+"px"; document.getElementById('contextmenu').style.display="block"; }); document.body.addEventListener('click',function (e){ document.getElementById('contextmenu').style.display="none"; }); } function menu1(){ alert("menu1がクリックされました。"); } function menu2(){ alert("menu2がクリックされました。"); } function menu3(){ alert("menu3がクリックされました。"); } </script> </head> <body onContextmenu="return false;"> <div id="contextmenu"> <ul> <li onClick="menu1()">menu1</li> <li onClick="menu2()">menu2</li> <li onClick="menu3()">menu3</li> </ul> </div> </body> </html>
これはそのままコピペして使えますので、自由にカスタマイズしてオリジナルの右クリックメニューを作成していただければと思います。
まとめ
今回はJavaScriptを使ったオリジナルの右クリックメニューを表示する方法について説明しました。意外と簡単に実装できたのではないでしょうか。
私自身の経験としても、JavaScriptを使って右クリックメニューを表示するなんて難しそうと思っていましたが、実際に作ってみると簡単なイベントハンドラの設定とスタイルシートの変更のみで実装できますので、思ったよりは難しくなかったです。それよりも、右クリックメニューの中でどんな動作を実装するのかの方が重要となってきますので、この記事を参考にして自由に作り込んでいただければと思います。