您的位置:首页 > Web前端 > JavaScript

javascript 右键菜单 支持多级菜单 支持不同节点展示不同菜单 兼容firefox和IE

2011-11-17 19:53 686 查看
手头上的项目需要实现javascript右键菜单功能,并支持不同节点显示不同的菜单,后期还要根据权限来控制菜单的显示项,这里先写一下如果实现标题所说的功能:

说明:参考了一些文章,自己再重构优化。

首先是一个hmtl文件,在里面定义了两个菜单rightMenu1和rightMenu2,并导入rightMenu.css和rightMenu.js,如下所示:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>自定义多级右键菜单</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link href="rightMenu.css" rel="stylesheet" type="text/css">
<script type="text/javascript" src="rightMenu.js"></script>
</head>
<body>
<div id="12345" oncontextmenu="(function(event){setRightMenu(event,'rightMenu1');})(event);return false;"
style="width:150px;height:20px;background:#E8FFE8;border:2px solid #336699;">
第一个右键菜单
</div></br>
<div id="56789" oncontextmenu="(function(event){setRightMenu(event,'rightMenu2');})(event);return false;"
style="width:150px;height:20px;background:#E8FFE8;border:2px solid #336699;">
第二个右键菜单
</div>

<div class="rightMenu"  id="rightMenu1" style="display:none">
<ul>
<li onclick="window.open('http://www.baidu.com')">打开百度</li>
<li>我有二级菜单
<ul>
<li>111</li>
<li>222</li>
<li>333</li>
</ul>
</li>
</ul>
</div>

<div class="rightMenu"  id="rightMenu2" style="display:none">
<ul>
<li onclick="window.open('http://www.csdn.com')">打开CSDN</li>
<li>我有二级菜单
<ul>
<li>111</li>
<li>222</li>
<li>文件
<ul>
<li>新建jsp文件</li>
<li>新建java文件</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
</body>
</html>


接下来是rightMenu.js:

/**
* 右键菜单功能,要使用右键功能时,在所在元素的标签中添加这样的配置:
*  oncontextmenu="(function(event){setRightMenu(event,'rightMenuId');})(event);return false;"
*   其中rightMenuId是指已经定义好的右键菜单的ID。
*  注意:
*  1、需要用到直线和箭头两个图片,在该Demo的images目录下可以找到
*  2、如要使用该Demo的菜单样式,div的class属性请设置为rightMenu,并在页面导入rightMenu.css
*  3、程序支持多级菜单,所以定义菜单时请使用div+ul标签进行定义:最外层用div,菜单内容用ul+li标签,如:
*  <div class="rightMenu"  id="rightMenu1" style="display:none">
<ul>
<li>菜单项1</li>
<li>
菜单项2,我有多级标签
<ul>
<li>111</li>
<li>222</li>
<li>333</li>
</ul>
</li>
</ul>
<div>
* 林树涛
* 2011年11月17日14:34:54
* */

//当前显示的右键菜单的ID
var currentRightMenuID;

//隐藏当前显示的右键菜单
function hideRightMenu(){
if(document.getElementById(currentRightMenuID)){
document.getElementById(currentRightMenuID).style.display = "none";
}
}
//点击页面其他地方时隐藏菜单
document.onclick = function (){
hideRightMenu();
};

/*
* 设置(配置)右键菜单,并弹出右键菜单
* rightMenuId:右键菜单的ID
* */
function setRightMenu(event,rightMenuId){
var event = event || window.event;
hideRightMenu();
currentRightMenuID = rightMenuId;
var oMenu = document.getElementById(rightMenuId);
var aUl = oMenu.getElementsByTagName("ul");
var aLi = oMenu.getElementsByTagName("li");
var showTimer = hideTimer = null;
var i = 0;
var maxWidth = maxHeight = 0;
var aDoc = [document.documentElement.offsetWidth, document.documentElement.offsetHeight];
var getOffset = {
top: function (obj) {
return obj.offsetTop + (obj.offsetParent ? arguments.callee(obj.offsetParent) : 0)
},
left: function (obj) {
return obj.offsetLeft + (obj.offsetParent ? arguments.callee(obj.offsetParent) : 0)
}
};
oMenu.style.display = "none";
for (i = 0; i < aLi.length; i++){
//为含有子菜单的li加上箭头
aLi[i].getElementsByTagName("ul")[0] && (aLi[i].className = "sub");
//鼠标移入
aLi[i].onmouseover = function (){
var oThis = this;
var oUl = oThis.getElementsByTagName("ul");

//鼠标移入样式
oThis.className += " active";
//显示子菜单
if (oUl[0]){
clearTimeout(hideTimer);
showTimer = setTimeout(function (){
for (i = 0; i < oThis.parentNode.children.length; i++){
oThis.parentNode.children[i].getElementsByTagName("ul")[0] &&
(oThis.parentNode.children[i].getElementsByTagName("ul")[0].style.display = "none");
}
oUl[0].style.display = "block";
/*
* offsetHeight/Width、offsetTop/offsetLeft
* 等返回的都是只读的并且以数字的形式返回像素值(例如,返回12,而不是'12px')。
* */
oUl[0].style.top = oThis.offsetTop + "px";
oUl[0].style.left = oThis.offsetWidth + "px";
setWidth(oUl[0]);
//最大显示范围
maxWidth = aDoc[0] - oUl[0].offsetWidth;
maxHeight = aDoc[1] - oUl[0].offsetHeight;
//防止溢出
maxWidth < getOffset.left(oUl[0]) && (oUl[0].style.left = -oUl[0].clientWidth + "px");
maxHeight < getOffset.top(oUl[0]) && (oUl[0].style.top = -oUl[0].clientHeight + oThis.offsetTop + oThis.clientHeight + "px")
},300);
}
};

//鼠标移出
aLi[i].onmouseout = function (){
var oThis = this;
var oUl = oThis.getElementsByTagName("ul");
//鼠标移出样式
oThis.className = oThis.className.replace(/\s?active/,"");
clearTimeout(showTimer);
hideTimer = setTimeout(function (){
for (i = 0; i < oThis.parentNode.children.length; i++){
oThis.parentNode.children[i].getElementsByTagName("ul")[0] &&
(oThis.parentNode.children[i].getElementsByTagName("ul")[0].style.display = "none");
}
},300);
};
}

oMenu.style.display = "block";
oMenu.style.top = event.clientY + "px";
oMenu.style.left = event.clientX + "px";
/*	setWidth(aUl[0]);
//最大显示范围
maxWidth = aDoc[0] - oMenu.offsetWidth;
maxHeight = aDoc[1] - oMenu.offsetHeight;
//防止菜单溢出
oMenu.offsetTop > maxHeight && (oMenu.style.top = maxHeight + "px");
oMenu.offsetLeft > maxWidth && (oMenu.style.left = maxWidth + "px");*/
return false;
}//##########end of setRightMenu

//取li中最大的宽度, 并赋给同级所有li
function setWidth(obj){
maxWidth = 0;
for (i = 0; i < obj.children.length; i++){
var oLi = obj.children[i];
var iWidth = oLi.clientWidth - parseInt(oLi.currentStyle ? oLi.currentStyle["paddingLeft"] : getComputedStyle(oLi,null)["paddingLeft"]) * 2
if (iWidth > maxWidth) maxWidth = iWidth;
}
for (i = 0; i < obj.children.length; i++){
obj.children[i].style.width = maxWidth + "px";
}
}


接下来时样式文件:rightMenu.css:

@CHARSET "UTF-8";
/*
鼠标右键样式文件
2011年11月17日15:28:47
* */

.rightMenu{
position:absolute;
top:-9999px;
left:-9999px;
font:12px/1.5 \5fae\8f6f\96c5\9ed1;
}
.rightMenu ul{
list-style-type:none;
float:left;
border:1px solid #979797;
background:#f1f1f1 url(images/rightMenu_line.png) 24px 0 repeat-y;
padding:2px;
box-shadow:2px 2px 2px rgba(0,0,0,.6);
}

.rightMenu ul li{
float:left;
clear:both;
height:24px;
cursor:pointer;
line-height:24px;
white-space:nowrap;
padding:0 30px;
}

.rightMenu ul li.sub{
background-repeat:no-repeat;
background-position:right 9px;
background-image:url(images/rightMenu_arrow.png);
}

.rightMenu ul li.active{
background-color:#f1f3f6;
border-radius:3px;
border:1px solid #aecff7;
height:22px;
line-height:22px;
background-position:right -8px;
padding:0 29px;
}

.rightMenu ul ul{
display:none;
position:absolute;
}


效果图如下:



第二个菜单:



用到的来个素材,小三角和直线:



直线:





























































就是一小点,为了看得清楚摆了好多个,呵呵。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: