OA系统,ERP系统这样的管理自动化系统。设计者们,总喜欢将菜单放在左侧。菜单太多了,分类折叠是必然的选择。这样既可以有力于菜单模块的管理,也可以方便操作。如下的一个菜单示例:
这样的菜单,我做了一个简单的。自己写了一个TheTree的类,效果还不错,贴上样式,还是杠杠的。
详细的源码可以访问我的github:
git@github.com:YeRuGeMiMi/TheTree.git
下面是我的开发过程:
1、生成菜单
我第一步写的菜单是直接硬编码在html中:
1 <ul> 2 <li><a href=‘#‘> 等待提交</a></li> 3 <li><a href=‘#‘ title=‘‘> 等待发布</a></li> 4 <li><a href=‘#‘ title=‘‘> 正式项目</a></li> 5 <li><a href=‘#‘ title=‘‘> 点此新增</a></li> 6 </ul>
可是,真是项目中因为权限控制的原因,是将这个菜单放在数据库中,根据权限来取得菜单树的。所以我想到了,能不能使用一个json保存菜单的数据,然后写个方法来生成菜单:
定义一个json:
1 var eljson=[{"name":"等待提交","link":"#"},{"name":"等待发布","link":"#"},{"name":"正式项目","link":"#"},{"name":"点此新增","link":"#"}]; 2 var usjson=[{"name":"查看用户","link":"#"},{"name":"用户列表","link":"#"},{"name":"会员用户","link":"#"},{"name":"超级用户","link":"#"}]; 3 var orjson=[{"name":"订单详情","link":"#"},{"name":"要货单","link":"#"},{"name":"退货单","link":"#"},{"name":"补货单","link":"#"}];
然后写一个一个TheTree的对象,定义一个生成方法:
1 function TheTree(tlist,eljson){ 2 this.list = document.querySelector(tlist); 3 this.create(eljson); 4 this.start(); 5 } 6 7 //菜单的初始状态 8 TheTree.prototype.start=function(){ 9 this.list.style.display="none"; 10 } 11 12 //创建节点 13 TheTree.prototype.create=function(eljson){ 14 if(!eljson){ 15 return false; 16 } 17 18 var ul=document.createElement("ul"); 19 //var eljson=eval(elements); 20 for(var i=0;i<eljson.length;i++){ 21 var li=document.createElement("li"); 22 var a=document.createElement("a"); 23 a.setAttribute("href",eljson[i].link); 24 var text=document.createTextNode(eljson[i].name); 25 a.appendChild(text); 26 li.appendChild(a); 27 ul.appendChild(li); 28 } 29 30 this.list.appendChild(ul); 31 32 }
start方法:定义菜单块的初始状态,我设定的是隐藏的(一般也是这样的)。
create方法:创建节点的方法,遍历json取得值。
而后,只要根据json和菜单的div创建一个TheTree的对象就可以了:
1 var tt = new TheTree(".FAQlist",eljson); 2 var pp = new TheTree(".Userlist",usjson); 3 var oo = new TheTree(".Orderlist",orjson);
菜单成功被创建了!
2、菜单动作
菜单的动作无非是“隐藏”,和“显示”。所以只要写个方法来控制它们的样式就可以了。
1 //动作 2 TheTree.prototype.jh=function(){ 3 if (this.list.style.display == "none") { 4 this.list.style.display = "block"; 5 this.status=true; 6 }else{ 7 this.list.style.display = "none"; 8 this.status=false; 9 } 10 }
做到这里,我本以为大功告成了。结果,却还有一个问题。
3、只打开一个
菜单分类之后,我需要的是:
可是,如果我的代码只写到上面这个地步,只能这样的:
为此,我想了想,突然来一个奇思妙想!
我为TheTree添加了一个属性status:
//属性状态 TheTree.prototype.status=false;
这个属性是用来记录,当前TheTree对象是否是展开的。因此,我可以讲建立所有的TheTree对象放到一个数组中:
1 var oarray=new Array(); 2 oarray[0]=tt; 3 oarray[1]=pp; 4 oarray[2]=oo;
再建立一个方法,判断这个数组中,除了对象自己本身外的其他对象的状态:
1 //只允许一个被点开 2 TheTree.prototype.open=function(objectArray){ 3 for(var i = 0;i<objectArray.length;i++){ 4 5 //判断对象是否是其本身 6 if (objectArray[i] === this) { 7 continue; 8 }; 9 10 if (objectArray[i].status) { 11 objectArray[i].jh();4 12 }; 13 14 } 15 }
调用这个open方法,就大功告成了!
1 document.getElementById("btn").onclick=function(){ 2 tt.jh(); 3 tt.open(oarray); 4 }; 5 6 document.getElementById("btn1").onclick=function(){ 7 pp.jh(); 8 pp.open(oarry); 9 }; 10 11 document.getElementById("btn2").onclick=function(){ 12 oo.jh(); 13 oo.open(oarray); 14 }
总结:
写了一下这个类,突然发现自己对JavaScript的面向对象知识生疏了,貌似我懂得太少了。写这么一个简单的类,都问了谷歌老师十几次,哎!看来要再去学习一下JavaScript面向对象的知识。