自己写了一个菜单,不是很灵活,只支持到三层的树,使用了一点ext的template、util包的一些功能,效果可参看下面的效果图样(懒得再写假数据,把文字模糊了,咯咯)。主要是各菜单之间的样式切换及ext的template传对象参数时有点麻烦。
1、请求数据js脚本,使用了pototype的Ajax,当时脑子不知咋想的,愣是没想到用ext的.......如ext也是一样的。
/*** 请求menu json串 *****/
function loadMenu(url){
var opt = {
// Use POST
method: 'post',
// Asynchronous must set true
asynchronous: true,
onSuccess: function showlResponse(originalRequest)
{
var menus = eval("("+originalRequest.responseText+")");
showAMenuList(menus.menu);
},
// Handle 404
on404: function(t) {
alert('Error 404: location "' + t.statusText + '" was not found.');
},
// Handle other errors
onFailure: function(t) {
alert('Error ' + t.status + ' -- ' + t.statusText);
}
}
//设置等待效果
var myGlobalHandlers = {
onCreate: function(){
// 等待特效
},
onComplete: function() {
if(Ajax.activeRequestCount == 0){
//Element.hide('DivSystemWorking');
// alert("菜单绘制完毕");
}
}
};
Ajax.Responders.register(myGlobalHandlers);
new Ajax.Request(url, opt);
}
json数据的格式如下
{menu: [{id:1,text:"菜单1",url:'',children:[ {id:2,text:"菜单2",url:'',children:[ {id:3,text:"菜单3",url:''} ]}, {id:4,text:"菜单4",url:'',children:[ {id:5,text:"菜单5",url:''} ]} ]}, [{id:6,text:"菜单1",url:'',children:[ {id:7,text:"菜单2",url:'',children:[ {id:8,text:"菜单3",url:''} ]}, {id:9,text:"菜单4",url:'',children:[ {id:10,text:"菜单5",url:''} ]} ]} ] }
2、 绘制一级菜单
function showAMenuList(menu_list){ // 一级菜单数量 var menuCount = menu_list.length; var tpl = new Ext.Template("<div id='{divId}' class='{cls}' onMouseOver='this.className=\"overDiv\"' onMouseOut='changeBG("+menuCount+")' οnclick='show2MenuList({menu2},\"{menuId}\",\"menuInfo\","+menuCount+",{i},\"{link}\");'>" +"<img src='{icon}' style='border:0px;width:22px;height:19px'> {title}</div>\t" +"<div id='{cid}' style=\"display:none;height:245px;width:100%;overflow-y:auto\"></div>\t"); for(var i=0; i<menuCount; i++){ var menuId = menu_list[i].menuId; var link = menu_list[i].href; var title = menu_list[i].text; var icon = menu_list[i].icon; var id = menu_list[i].id; // alert("aa: "+Ext.util.JSON.encode(menu_list[i].children)); if(i==0){ tpl.append('menuList', {divId:menuId+""+i,menuId:menuId,cid:"menuInfo"+i, menu2:Ext.util.JSON.encode(menu_list[i].children), cls:"selected", title:title, icon:icon, url:link, id:id, i:i}); // 绘制二级菜单 if(menu_list[i].children!=null && menu_list[i].children.length>0){ var menu2 = menu_list[i].children; show2MenuList(menu2,menuId,"menuInfo",menuCount,i); } }else{ tpl.append('menuList', {divId:menuId+""+i,menuId:menuId,cid:"menuInfo"+i, menu2:Ext.util.JSON.encode(menu_list[i].children), cls:"body", title:title, icon:icon, url:link, id:id, i:i}); } } }
3、绘制二级菜单
//二级菜单显示-- 参数: 菜单集合,父divID,子divId,循环的次数 function show2MenuList(menu2,divId,cid,p_count,i,url){ // alert(typeof(menu2)); // 保存选中状态 if(selectedDiv!=null) selectedDiv.className = "body"; selectedDiv = document.getElementById(divId+i); selectedDiv.className = "selected"; selectedMenu=null; selectedChildMenu = null; //展开二级菜单Div var hh = document.body.clientHeight? document.body.clientHeight : document.body.scrollHeight; var mh = parseInt(hh)-((p_count+1)*28)-78; // 隐藏未被选中的菜单项 for(var k=0; k<p_count; k++){ if("menuInfo"+k==cid+i){ document.getElementById(cid+i).style.display = "block"; document.getElementById(cid+i).style.height=mh; }else if(document.getElementById("menuInfo"+k)!=null){ document.getElementById("menuInfo"+k).style.display = "none"; document.getElementById("menuInfo"+k).innerHTML=""; } } // 判断当前点击的一级菜单是否有子菜单,有子菜单时显示子菜单,没有子菜单时直接打开链接并返回 if(menu2==null || menu2.length<1){ callDateList(url); return; } var count = menu2.length; var s=""; for(var j=0; j<count; j++){ var menuId = menu2[j].menuId; var url = menu2[j].href; var title = menu2[j].text; var tid = menu2[j].id; //计算二级菜单下三级菜单的数量 var tcount=0; var menu3=null; if(menu2[j].children!=null && menu2[j].children.length>0){ menu3 = tcount=menu2[j].children tcount=menu3.length; callDateList(menu2[j].children[0].href); }else{ // 如果有三级子菜单 callDateList(url); } // alert("menu3: "+Ext.util.JSON.encode(menu3)); if(j==0){ s+="<div id='"+menuId+j+"' class='menuInfo-selected' onMouseOver='this.className=\"menuInfo-mouseover\"' onMouseOut='changeBStyle(\""+menuId+"\","+count+")' οnclick='showThirdMenuList("+Ext.util.JSON.encode(menu3)+",\""+menuId+"\",\"thirdMenu\","+count+","+j+",\""+url+"\")'>"+title+"</div>"; if(tcount>0){ var str=callThirdMenu(menu2[j].children); s+="<div id='thirdMenu"+j+"' style='display:block;height:0px;width:100%;'>"+str+"</div>\t"; }else{ s+="<div id='thirdMenu"+j+"' style='display:none;height:0px;width:100%;'></div>\t"; } }else{ s+="<div id='"+menuId+j+"' class='main' onMouseOver='this.className=\"menuInfo-mouseover\"' onMouseOut='changeBStyle(\""+menuId+"\","+count+")' οnclick='showThirdMenuList("+Ext.util.JSON.encode(menu3)+",\""+menuId+"\",\"thirdMenu\","+count+","+j+",\""+url+"\")'>"+title+"</div>"; s+="<div id='thirdMenu"+j+"' style='display:none;width:100%;overflow-y:auto'></div>\t"; } } document.getElementById(cid+i).innerHTML=s; }
4、绘制三级菜单
function showThirdMenuList(menu3,divId,cid,count,i,url){ selectedMenu=document.getElementById(divId+i); selectedMenu.className="menuInfo-selected"; selectedChildMenu = null; // alert(document.getElementById(cid+i)); // 没有三级子菜单的情况下,切换样式,直接打开链接,返回 if(menu3.length==0 || document.getElementById(cid+i).style.display=="block"){ for(var j=0; j<count; j++){ if(document.getElementById("thirdMenu"+j)!=null) document.getElementById("thirdMenu"+j).style.display = "none"; } callDateList(url); return; } // 在有三级子菜单的情况下,切换样式并黙认打开三级菜单的第一个菜单对应的链接 callDateList(menu3[0].href); for(var k=0; k<count; k++){ if("thirdMenu"+k==cid+i){ document.getElementById(cid+i).style.display="block"; document.getElementById(cid+i).style.height=parseInt(menu3.length) * 28 +"px"; }else if(document.getElementById("thirdMenu"+k)!=null){ document.getElementById("thirdMenu"+k).style.display = "none"; } } document.getElementById(cid+i).innerHTML=callThirdMenu(menu3); } function callThirdMenu(menu3){ var s = ""; var count = menu3.length; for(var k=0; k<count; k++){ var id = menu3[k].menuId; var url = menu3[k].href; var title = menu3[k].text; if(k==0){ s += "<div id='"+id+k+"' class='childMenu-selected' style='display:block' onMouseOver='this.className=\"childMenu-mouseOver\"' onMouseOut='changeCStyle(\""+id+"\","+count+")' onClick='showResultDiv(\""+id+k+"\",\""+title+"\",\""+url+"\")'>"+title+"</div>"; // callDateList(url); }else{ s += "<div id='"+id+k+"' class='childMenu' style='display:block' onMouseOver='this.className=\"childMenu-mouseOver\"' onMouseOut='changeCStyle(\""+id+"\","+count+")' onClick='showResultDiv(\""+id+k+"\",\""+title+"\",\""+url+"\")'>"+title+"</div>"; } } return s; }
// 鼠标单击事件分配对应的结果在展示区显示 function callDateList(url){ if(url=="" || url==null){ blankPage(); return; }else{ loadResultPage(url); } } // 三级菜单调用函数 function showResultDiv(menuId,name,url){ if(selectedChildMenu!=null) selectedChildMenu.className="childMenu" selectedChildMenu = document.getElementById(menuId); selectedChildMenu.className = "childMenu-selected"; if(url=="" || url==null){ blankPage(); // 调用一个空页面 }else{ loadResultPage(url); // 加面页面在右边功能区 } }
5、样式切换
/**** 样式切换 开始**/ function changeBG(count) { if (selectedDiv == "" || selectedDiv == null) { for (var i = 0; i < count; i++) { if (i == 0) { document.getElementById("menu0").className = "selected"; } else { document.getElementById("menu" + i).className = "body"; } } } else { for (var i = 0; i < count; i++) { if (selectedDiv.id == "menu" + i) { document.getElementById("menu" + i).className = "selected"; } else { document.getElementById("menu" + i).className = "body"; } } } } function changeBStyle(flag,count){ if (selectedMenu == null || selectedMenu == "") { for (var i = 0; i < count; i++) { if (i==0) { document.getElementById(flag+0).className = "menuInfo-selected"; } else { document.getElementById(flag+i).className = "main"; } } }else{ for (var i = 0; i < count; i++) { if (selectedMenu.id==flag+i) { document.getElementById(flag+i).className = "menuInfo-selected"; } else { document.getElementById(flag+i).className = "main"; } } } } function changeCStyle(flag, count){ if (selectedChildMenu==null || selectedChildMenu=="") { for (var i = 0; i < count; i++) { if (i==0) { document.getElementById(flag+0).className = "childMenu-selected"; } else { document.getElementById(flag+i).className = "childMenu"; } } }else{ for (var i = 0; i < count; i++) { if(selectedChildMenu.id==flag+i) { document.getElementById(flag+""+i).className = "childMenu-selected"; } else { document.getElementById(flag+i).className = "childMenu"; } } } } /******* 样式结束******/
6、样式文件
.feed-list {
border: 1px solid white;
display: block;
text-decoration: none;
margin-bottom: 0px;
padding: 0px 0px 0px 0px;
}
.feed-list div.body {
padding: 3px 0px 0px 3px;
font: bold 12px tahoma, verdana, helvetica;
color: #1641A0;
display: block;
-moz-outline: none;
border-top: 1px solid #6D91CD;
cursor: pointer;
margin-bottom: 1px;
text-indent: 10px;
width: 100%;
background-image: url(../images/tr-bg.gif);
background-repeat: repeat-x;
height: 27px;
line-height:18px;
}
.feed-list div.overDiv {
padding: 3px 0px 0px 3px;
font: bold 12px tahoma, verdana, helvetica;
color: #1641A0;
display: block;
-moz-outline: none;
border-top: 1px solid #6D91CD;
cursor: pointer;
margin-bottom: 1px;
text-indent: 10px;
width: 100%;
background-image: url(../images/tr-over-bg.gif);
background-repeat: repeat-x;
height: 27px;
line-height:18px;
}
.feed-list .selected {
cursor: pointer;
background-image: url(../images/tr-light-bg.gif);
background-repeat: repeat-x;
padding: 3px 0px 0px 3px;
font: bold 12px tahoma, verdana, helvetica;
color: #1641A0;
display: block;
-moz-outline: none;
border-bottom: 1px solid #6D91CD;
border-top: 1px solid #6D91CD;
cursor: pointer;
margin-bottom: 1px;
text-indent: 10px;
width: 100%;
height: 27px;
line-height:18px;
}
.menuInfo {
width: 100%;
height: 27px;
padding: 5px;
display: block;
font-size: 12px;
color: #1641A0;
cursor: pointer;
line-height: 18px;
margin-top: 0px;
text-decoration: none;
background-image: url(../images/small_icon.gif);
background-position: 20 7 0 0;
background-color: #E3EEFD;
background-repeat: no-repeat;
text-indent: 30px;
}
.main {
width: 100%;
height: 27px;
padding: 5px;
display: block;
font-size: 12px;
color: #1641A0;
cursor: pointer;
line-height: 18px;
margin-top: 0px;
text-decoration: none;
background-image: url(../images/small_icon.gif);
background-position: 20 7 0 0;
background-color: #E3EEFD;
background-repeat: no-repeat;
text-indent: 35px;
}
.menuInfo-mouseover {
width: 100%;
height: 27px;
padding: 5px;
display: block;
font-size: 12px;
color: #1641A0;
cursor: pointer;
line-height: 18px;
margin-top: 0px;
text-decoration: none;
text-indent: 35px;
background-image: url(../images/small_over_icon.gif);
background-position: 20 7 0 0;
background-repeat: no-repeat;
background-color: #F0F7FF;
}
.menuInfo-selected {
width: 100%;
height: 27px;
padding: 5px;
display: block;
font-size: 12px;
color: #1641A0;
cursor: pointer;
line-height: 18px;
margin-top: 0px;
text-decoration: none;
text-indent: 35px;
background-image: url(../images/small_change_icon.gif);
background-position: 20 7 0 0;
background-repeat: no-repeat;
background-color: #F0F7FF;
}
.childMenu {
width: 100%;
height: 20px;
padding: 5px;
display: block;
font-size: 12px;
color: #1641A0;
cursor: pointer;
line-height: 18px;
margin-top: 0px;
text-decoration: none;
text-indent: 50px;
background-image: url(../images/round_blue.gif);
background-position: 40 8 0 0;
background-repeat: no-repeat;
}
.childMenu-mouseOver {
width: 100%;
height: 20px;
padding: 5px;
display: block;
font-size: 12px;
color: blue;
cursor: pointer;
line-height: 18px;
margin-top: 0px;
text-decoration: none;
text-indent: 50px;
background-image: url(../images/round_green.gif);
background-position: 40 8 0 0;
background-repeat: no-repeat;
}
.childMenu-selected {
width: 100%;
height: 20px;
padding: 5px;
display: block;
font-size: 12px;
color: red;
cursor: pointer;
line-height: 18px;
margin-top: 0px;
text-decoration: none;
text-indent: 50px;
background-image: url(../images/round_orange.gif);
background-position: 40 8 0 0;
background-repeat: no-repeat;
}
7、页面代码
<body id="feedViewer" style="overflow: auto">
<div id="header"></div>
<div id="menuDiv" style='background-color: #E3EEFD;'>
<div id="menuList" class="feed-list">
</div>
</div>
<div id="main"></div>
</body>