既然是右鍵菜單,首先就要重寫下右鍵單擊的功能。先準備一個用來右鍵單擊的元素:html
<div id="test"></div>
簡要定義下高度、寬度和背景色:學習
#test { width:200px; height:200px; background-color:green; }
接下來就來編寫這個div的右鍵單擊事件,因爲元素默認都有右鍵菜單,因此咱們首先要去掉默認默認菜單:this
//去掉默認的contextmenu事件,不然會和右鍵事件同時出現。 document.getElementById("test").oncontextmenu = function(e){ e.preventDefault(); };
而後從新定義鼠標單擊操做:spa
document.getElementById("test").onmousedown = function(e){ //右鍵 if(e.button ==2){ alert("你點擊了右鍵"); }else if(e.button ==0){ //左鍵 alert("你點擊了左鍵"); }else if(e.button ==1){ //按下滾輪 alert("你按下了滾輪"); } }
如上,各個鍵的單擊的功能都改寫了下,寫右鍵菜單的話,咱們只須要將顯示菜單的代碼放在e.button == 2的狀況下就行。code
改寫了右鍵單擊的功能,接下來要作顯示菜單的功能,首先準備幾個簡單的元素構成菜單:htm
<ul class="context-menu" id="ct"> <li class="context-menu-item">option1</li> <li class="context-menu-item">option2</li> <li class="context-menu-item">option3</li> </ul>
一樣加上簡單的樣式使它看起來更像樣點:blog
ul.context-menu { padding:0; margin:0; position:absolute; /*只能是absolute或fixed*/ } ul.context-menu li { list-style:none; width:100px; height:20px; line-height:20px; text-align:center; border:solid 1px; background-color:#CCC; display:block; } ul.context-menu li:hover { background-color:#C0C0C0; cursor:context-menu; }
到這裏,網頁基本上是這個樣子:seo
哦,一開始菜單應該是隱藏的,因此應該給ul加上display:none;屬性,這樣網頁上一開始就只能看到綠色的方塊:事件
ul.context-menu { padding:0; margin:0; display:none; position:absolute; /*只能是absolute或fixed*/ }
而後改寫綠色方塊的右鍵單擊事件,使得右鍵單擊時菜單獲得顯示,前面說過了,只要將顯示菜單的代碼寫到e.button == 2的狀況下面就行了,像這樣:ip
if(e.button ==2){ document.getElementById("ct").style.display = "block"; }
這個時候的基本樣子就是打開頁面看到一個綠色方塊,右鍵單擊綠色方塊,左上角出現菜單。右鍵菜單有一個基本特性就是菜單顯示後,若鼠標再點在菜單之外的其它地方,菜單應該隱藏,因此咱們還應該重寫下這個方塊的左鍵單擊事件、中鍵單擊事件、失去焦點事件(鼠標點在綠色方塊之外),在這些事件中加上隱藏菜單的代碼,基本上就像這樣:
document.getElementById("test").onmousedown = function(e){ //右鍵 if(e.button ==2){ document.getElementById("ct").style.display = "block"; }else if(e.button ==0){ //左鍵 document.getElementById("ct").style.display = "none"; }else if(e.button ==1){ //按下滾輪 document.getElementById("ct").style.display = "none"; } } //失去焦點事件 document.getElementById("test").onblur = function(e){ document.getElementById("ct").style.display = "none"; }
這個時候已經基本像樣了,打開頁面,會看到一個綠色方塊,右鍵單擊方塊,左上角會顯示菜單,鼠標再點菜單之外其它地方,菜單會消失,有點味道了。右鍵菜單還有一個基本屬性,就是菜單位置緊跟鼠標點擊的位置,因此咱們在右鍵單擊事件中,還須要加上給菜單定位的代碼,爲了能經過X、Y定位,菜單的posiotion設置成absolute或fixed是頗有必要的,建議absolute。這個時候右鍵單擊事件的處理代碼基本上像這樣:
if(e.button ==2){ var x = e.clientX;//獲取鼠標單擊點的X座標 var y = e.clientY;//獲取鼠標單擊點的Y座標 //設置菜單的位置 document.getElementById("ct").style.left = x + "px"; document.getElementById("ct").style.top = y + "px"; document.getElementById("ct").style.display = "block"; }
到這裏,頁面基本上已經頗有味道了,右鍵在綠色方塊內任意地方單擊,就會在該地方顯示菜單,鼠標再點菜單之外其它地方,菜單會消失。
接下來,很重要的一點,就是鼠標移入菜單內的時候,咱們必須取消綠色方塊失去焦點時隱藏菜單的功能。由於在點擊菜單項的時候,會先觸發綠色方塊的失去焦點(onblur)事件,而後才觸發onclick事件,咱們在前面定義了方塊失去焦點就隱藏菜單的,而菜單被隱藏(display被設置成none,基本等同從頁面移除了這個元素)時,它的onclick事件就不會被觸發了;因此咱們要想辦法在菜單項的onclick事件被觸發前阻止綠色方塊的onblur事件被觸發,基本解決辦法就是在鼠標移到菜單項上面時取消方塊的onblur事件,鼠標移出菜單項時恢復方塊的onblur事件,像這樣:
//給每一個菜單項添加事件處理 var items = document.getElementsByClassName("context-menu-item"); for(var i=0; i < items.length; i++){ //在定義onclick事件以前,必須設置取消test元素的onblur事件,不然onclick事件失效,由於click先觸發的是test元素的onblur事件,該事件有移除菜單的操做,纔會致使後面的代碼失效 items.item(i).onmouseover = function(e){ document.getElementById("test").onblur = undefined; } //鼠標移出菜單時,仍是要將test的onblur事件還原 items.item(i).onmouseleave = function(e){ document.getElementById("test").onblur = function(e){ document.getElementById("ct").style.display = "none"; } } }
處理好這個細節,咱們就能夠放心大膽地寫菜單的功能了,功能根據實際須要來寫,這裏就沒什麼好介紹的了。
哦,還有一個細節要處理,就是代碼寫到這裏,右鍵單擊方塊的時候會同時出現系統默認菜單和咱們本身的菜單,這是由於右鍵單擊的時候同時觸發了菜單元素的右鍵單擊事件,咱們同時要屏蔽菜單元素的右鍵默認事件:
document.getElementById("ct").oncontextmenu = function(e){ e.preventDefault(); };
到這裏,基本全部細節都介紹到了,接下來最重要的就是將上面這些細節組裝成完整的DEMO了,示例以下:
<!doctype html> <html> <head> <meta charset="utf-8"> <title>網頁右鍵菜單</title> <!-- 思路: 1.寫出右鍵點擊事件; 2.寫出菜單功能; 3.關聯右鍵功能和菜單,學習使用定位 --> <style> #test { width:200px; height:200px; background-color:green; } ul.context-menu { padding:0; margin:0; display:none; position:absolute; /*只能是absolute或fixed*/ } ul.context-menu li { list-style:none; width:100px; height:20px; line-height:20px; text-align:center; border:solid 1px; background-color:#CCC; display:block; } ul.context-menu li:hover { background-color:#C0C0C0; cursor:context-menu; } </style> <script> //var t = document.getElementById("test"); window.onload = function(){ var clicked_ele;//全局變量,用於記錄被右鍵單擊呼出菜單的元素 //去掉默認的contextmenu事件,不然會和右鍵事件同時出現。 document.getElementById("test").oncontextmenu = function(e){ e.preventDefault(); }; document.getElementById("ct").oncontextmenu = function(e){ e.preventDefault(); }; document.getElementById("test").onmousedown = function(e){ if(e.button ==2){//右鍵 var x = e.clientX;//獲取鼠標單擊點的X座標 var y = e.clientY;//獲取鼠標單擊點的Y座標 //設置菜單的位置 document.getElementById("ct").style.left = x + "px"; document.getElementById("ct").style.top = y + "px"; document.getElementById("ct").style.display = "block"; clicked_ele = this; }else if(e.button ==0){ //左鍵 document.getElementById("ct").style.display = "none"; }else if(e.button ==1){ //按下滾輪 document.getElementById("ct").style.display = "none"; } } document.getElementById("test").onblur = function(e){ document.getElementById("ct").style.display = "none"; } //給每一個菜單項添加事件處理 var items = document.getElementsByClassName("context-menu-item"); for(var i=0; i < items.length; i++){ //在定義onclick事件以前,c必須設置取消test元素的onblur事件,不然onclick事件失效,由於click先觸發的是test元素的onblur事件,該事件有移除菜單的操做,纔會致使後面的代碼失效 items.item(i).onmouseover = function(e){ document.getElementById("test").onblur = undefined; } //鼠標移出菜單時,仍是要將test的onblur事件還原 items.item(i).onmouseleave = function(e){ document.getElementById("test").onblur = function(e){ document.getElementById("ct").style.display = "none"; } } items.item(i).onclick = function(e){ e.stopPropagation();//爲避免引發其它錯誤,阻止冒泡很重要 console.log(this.innerHTML + ":" + clicked_ele.innerHTML); document.getElementById("ct").style.display = "none"; } } } </script> </head> <body> <ul class="context-menu" id="ct"> <li class="context-menu-item">option1</li> <li class="context-menu-item">option2</li> <li class="context-menu-item">option3</li> </ul> <div id="test" tabindex="2">我是美膩大方的綠方塊</div> </body> </html>
效果圖: