自定义右键菜单

前言

 分享一下今天下午做的一个小东西,就是自定义右键菜单了,代码呢,写的比较粗糙,但是大致完成了需求,恩,其实师姐也分享过,但是呢,自己动手之后才更掌握的更好。

实现的效果如下或者点击这里
1.gif

contextmenu法

1
2
3
4
5
6
7
8
9
10
11
<div contextmenu="mymenu" >
<div class="context">这里有一个菜单,请在firefox打开哟</div>
<menu id="mymenu" type="context">
<menuitem label="呼呼" icon="1.jpg" onclick="doSomething()"></menuitem>
<menuitem label="嘻嘻" icon="2.jpg" onclick="doSomethingElse()"></menuitem>
<menu label="哈哈">
<menuitem label="呼呼" icon="1.jpg" onclick="doSomething()"></menuitem>
<menuitem label="嘻嘻" icon="2.jpg" onclick="doSomethingElse()"></menuitem>
</menu>
</menu>
</div>

使用小TIP

  • 该属性仅在firefox浏览器有效,测试请在firefox下,所以局限性比较强
  • 属性contextmenu的值与menu标签id的值对应;
  • 添加menu标签时,要加上type=”context” 这个属性,要不然不灵
  • 在标签里添加上icon属性,可以添加小图标
  • 想要子菜单的效果,直接在menu标签中再增加menu标签,看上事例即可明白;

素不素hin简单~~~

JS纯手工打造法

用contextmenu只能在firefox下使用,且只能在原有的菜单上新增菜单键,所以呢,下面用js来纯手工打造,原理呢大概就是点击某个特定的区域之后,获取该点的位置,在该处添加一个菜单列表,比如用ul来做,恩!想想也是简单的呢,代码如下,该注释的都注释了。

1
2
3
4
5
6
7
8
9
10
11
<div class="menu context">这里还有一个菜单,呼呼</div>
<div class="menu context">这里还有一个菜单,嘻嘻</div>
<div class="menu context">这里还有一个菜单,哟哟</div>
<div id="supermenu" style="display: none;">
<ul>
<li><a href="#">menu1</a></li>
<li><a href="#">menu2</a></li>
<li><a href="#">menu3</a></li>
</ul>
</div>
</div>

这里,还有一个点要注意的事,我们可以用鼠标右键事件,也可以用HTML5里有所的contextmenu事件来写我们需要的功能。

contextmenu事件法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
$=function(element){
return document.querySelectorAll(element);
}
var mymenu=document.getElementById("supermenu");
//监听contextmenu事件
for(var i=0;i<$(".menu").length;i++){
$(".menu")[i].addEventListener("contextmenu",function(e){
e.preventDefault();//阻止原有的菜单
e.returnValue=false;//在IE中阻止原有的菜单
mymenu.style.cssText='display: block;'; //先显示后才能获取menu的高宽
var menuwidth=mymenu.offsetWidth;//获取自定义菜单的高宽
var menuheight=mymenu.offsetHeight;
var clientwidth=document.documentElement.clientWidth;//获取当前可视窗口的高宽
var clientheight=document.documentElement.clientHeight;
if(clientheight-e.pageY>=menuheight){ //底下有足够空间时
mymenu.style.top=e.pageY+"px";//菜单在下方
}else{
mymenu.style.top=(e.pageY-menuheight)+"px";
}
if(clientwidth-e.pageX>=menuwidth){ //右边有足够空间
mymenu.style.left=e.pageX+"px";//菜单有右边
}else{
mymenu.style.left=(e.pageX-menuwidth)+"px";
}
console.log(clientheight-e.pageY,clientwidth-e.pageX);
})
document.body.addEventListener("click",function(e){ //点击其他地方菜单消失,可恢复默认的菜单事件
mymenu.style.cssText='display: none;';
})
}

小TIP

在兼容DOM浏览器中,使用event.preventDefault()取消,在IE中,将event.returnValue的值设为false即可。
其他的点差不多都注释了,就不多说了

mousedown事件法

可以根据mousedown事件对象的button值来判断

鼠标事件 button值 备注
click 0 单击鼠标左键
click 1 单击鼠标中键
mousedown 0 按下鼠标左键
mousedown 1 按下鼠标中键
mousedown 2 按下鼠标右键

click事件只会在单击鼠标左键和中键时触发,单击右键时不会触发

所以呢,只要把上面的代码轻轻一改就可以了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<script type="text/javascript">
$=function(element){
return document.querySelectorAll(element);
}
var mymenu=document.getElementById("supermenu");
for(var i=0;i<$(".menu").length;i++){
$(".menu")[i].addEventListener("mousedown",function(e){
if(window.event) e=window.event; //兼容性
if(e.button==2){
document.oncontextmenu=function(e){
e.preventDefault();//阻止原有的菜单,可以不用再加e.returnValue=false;亲测。
}
mymenu.style.cssText='display: block;'; //先显示后才能获取menu的高宽
var menuwidth=mymenu.offsetWidth;//获取自定义菜单的高宽
var menuheight=mymenu.offsetHeight;
console.log(menuheight,menuwidth);
var clientwidth=document.documentElement.clientWidth;//获取当前可视窗口的高宽
var clientheight=document.documentElement.clientHeight;
if(clientheight-e.pageY>=menuheight){ //底下有足够空间时
mymenu.style.top=e.pageY+"px";//菜单在下方
}else{
mymenu.style.top=(e.pageY-menuheight)+"px";
}
if(clientwidth-e.pageX>=menuwidth){ //右边有足够空间
mymenu.style.left=e.pageX+"px";//菜单有右边
}else{
mymenu.style.left=(e.pageX-menuwidth)+"px";
}
console.log(clientheight-e.pageY,clientwidth-e.pageX);
}
})
document.body.addEventListener("click",function(e){ //点击其他地方菜单消失,可恢复默认的菜单事件
mymenu.style.cssText='display: none;';
document.oncontextmenu=function(e){}//需要加上这个,否则还是不可恢复原来的默认菜单事件
})
}

就到这里啦,可以试试嗷

源码戳这里


参考:
https://simmin.github.io/2016/07/22/contextmenu/