前端无限极菜单

html代码实现

<!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>   
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />   
<meta name="author" content="56gee 39℃" />   
<title>Jquery实现无限极树状结构</title>   
<style type="text/css">   
div, ul, li {   
    margin: 0px;   
    padding: 0px;   
    list-style-type: none;   
}   
  
body {   
    background-color: #FFFFFF;   
    font-size: 12px;   
    margin: 0px;   
    padding: 0px;   
}   
  
#TreeList {   
    background-color: #FFFFFF;   
    margin-top: 6px;   
    margin-right: 9px;   
    margin-bottom: 6px;   
    margin-left: 9px;   
    border: 1px solid #5d7b96;   
    padding-bottom: 6px;   
    padding-left: 6px;   
}   
#TreeList .mouseOver {   
    background-color: #FAF3E2;   
}   
  
#TreeList .ParentNode {   
    line-height: 21px;   
    height: 21px;   
    margin-top: 2px;   
    clear: both;   
}   
  
#TreeList .ChildNode {   
    background-image: url(Sys_ModuleIcos.png);   
    background-position: 15px -58px;   
    padding-left: 39px;   
    line-height: 21px;   
    background-repeat: no-repeat;   
    border-top-width: 0px;   
    border-right-width: 0px;   
    border-bottom-width: 1px;   
    border-left-width: 0px;   
    border-top-style: dashed;   
    border-right-style: dashed;   
    border-bottom-style: dashed;   
    border-left-style: dashed;   
    border-top-color: #aabdce;   
    border-right-color: #aabdce;   
    border-bottom-color: #aabdce;   
    border-left-color: #aabdce;   
    cursor: default;   
    clear: both;   
    height: 21px;   
    color: #314f6a;   
}   
  
#TreeList .title {   
    float: left;   
}   
#TreeList .input {   
    font-size: 12px;   
    line-height: 18px;   
    color: #FFF;   
    height: 16px;   
    background-color: #3F6B8F;   
    width: 120px;   
    text-align: center;   
    margin-top: 1px;   
    border-top-width: 1px;   
    border-right-width: 1px;   
    border-bottom-width: 1px;   
    border-left-width: 1px;   
    border-top-style: solid;   
    border-right-style: solid;   
    border-bottom-style: solid;   
    border-left-style: solid;   
    border-top-color: #1F3547;   
    border-right-color: #FFF;   
    border-bottom-color: #FFF;   
    border-left-color: #1F3547;   
    float: left;   
}   
#TreeList .editBT {   
    float: left;   
    overflow: visible;   
}   
#TreeList .editBT .ok {   
    background-image: url(Sys_ModuleIcos.png);   
    background-repeat: no-repeat;   
    background-position: 0px -89px;   
    height: 13px;   
    width: 12px;   
    float: left;   
    margin-left: 3px;   
    padding: 0px;   
    margin-top: 3px;   
    cursor: pointer;   
}   
#TreeList .editBT .cannel {   
    background-image: url(Sys_ModuleIcos.png);   
    background-repeat: no-repeat;   
    background-position: 0px -120px;   
    float: left;   
    height: 13px;   
    width: 12px;   
    margin-left: 3px;   
    padding: 0px;   
    margin-top: 3px;   
    cursor: pointer;   
}   
  
#TreeList .editArea {   
    float: right;   
    color: #C3C3C3;   
    cursor: pointer;   
    margin-right: 6px;   
}   
  
#TreeList .editArea span {   
    margin: 2px;   
}   
  
#TreeList .editArea .mouseOver {   
    color: #BD4B00;   
    border-top-width: 1px;   
    border-right-width: 1px;   
    border-bottom-width: 1px;   
    border-left-width: 1px;   
    border-top-style: solid;   
    border-right-style: solid;   
    border-bottom-style: solid;   
    border-left-style: solid;   
    border-top-color: #C9925A;   
    border-right-color: #E6CFBB;   
    border-bottom-color: #E6CFBB;   
    border-left-color: #C9925A;   
    background-color: #FFFFFF;   
    margin: 0px;   
    padding: 1px;   
}   
  
#TreeList .ParentNode .title {   
    color: #314f6a;   
    cursor: pointer;   
    background-image: url(Sys_ModuleIcos.png);   
    background-repeat: no-repeat;   
    padding-left: 39px;   
}   
  
#TreeList .ParentNode.show .title {   
    font-weight: bold;   
    background-position: 3px -27px;   
}   
  
#TreeList .ParentNode.hidden .title {   
    background-position: 3px 4px;   
}   
  
#TreeList .ParentNode .editArea {   
    color: #999;       
}   
#TreeList .ParentNode.show {   
    background-color: #d1dfeb;   
    border-top-width: 0px;   
    border-right-width: 0px;   
    border-bottom-width: 1px;   
    border-left-width: 1px;   
    border-top-style: solid;   
    border-right-style: solid;   
    border-bottom-style: solid;   
    border-left-style: solid;   
    border-top-color: #5d7b96;   
    border-right-color: #5d7b96;   
    border-bottom-color: #5d7b96;   
    border-left-color: #5d7b96;   
}   
  
#TreeList .ParentNode.hidden {   
    border-top-width: 0px;   
    border-right-width: 0px;   
    border-bottom-width: 1px;   
    border-left-width: 0px;   
    border-top-style: dashed;   
    border-right-style: dashed;   
    border-bottom-style: dashed;   
    border-left-style: dashed;   
    border-top-color: #aabdce;   
    border-right-color: #aabdce;   
    border-bottom-color: #aabdce;   
    border-left-color: #aabdce;   
}   
  
#TreeList .Row {   
    clear: both;   
    margin-left: 24px;   
    background-image: url(Sys_ModuleIcos2.png);   
    background-repeat: repeat-y;   
    background-position: 7px 0px;   
} 
#TreeList img {
    width: 21px;
    border: 0px;
    vertical-align: middle;
}  
</style>   
<script type="text/javascript" src="jquery-1.5.min.js"></script>   
<script type="text/javascript"> 

$(document).ready(function(e) {   
    var TreeName = 'TreeList';//树状ID   
    var PrentNodeClass = 'ParentNode';//父节点的标识   
    var ChildNodeClass = 'ChildNode';//没有下级子节点的标识   
    var ChildrenListClass = 'Row';//子节点被包着的外层样式   
    var NewNodeName = '新建目录';//默认新建节点的名称   
    var Orititle = 'Temptitle';//保存原来名称的属性名称   
       
    var TModuleNode,TChildNode,TModuleNodeName;   


    TModuleNode = $('#TreeList .'+PrentNodeClass);//顶层节点   
    TChildNode = $('.'+ChildNodeClass);   
    TModuleNodeName = $('#TreeList .' + PrentNodeClass + ' .title');//顶层节点名称   
    TModuleNode.removeClass('show').addClass('hidden');   
    if(TModuleNode.next().hasClass(ChildrenListClass)){   
        TModuleNode.next().css('display','none');//紧跟的下一个是子节点   
    }   
       
    //========================编辑区域的HTML源码==============================   
    function EditHTML(NewName){   
      var str = `<div class=title data-visible=1>${NewName}</div>   
      <div class=editBT></div>
      <img src=yes.png class=judgeImg /> 
      <div class=editArea><span>[编辑]</span><span>[添加同级目录]</span><span>[添加下级目录]</span><span>[删除]</span></div>`;
      return str;   
    }       
       
    //==========================树状展开收缩的效果============================   
    TModuleNodeName.click(function(){   
        TModuleNodeName_Click($(this));   
    });   

       
    //-------------------------------(定义)----------------------------------   
    function TModuleNodeName_Click(Obj){   
        if(Obj.has('input').length==0){//非编辑模式下进行   
          var tempNode = Obj.parent();   
          if(tempNode.hasClass('hidden')){   
              tempNode.removeClass('hidden').addClass('show');   
              if(tempNode.next().hasClass(ChildrenListClass)){   
                tempNode.next().css('display','');   
              }   
          }   
          else{   
              tempNode.removeClass('show').addClass('hidden');   
              if(tempNode.next().hasClass(ChildrenListClass)){   
                  tempNode.next().css('display','none');   
              }   
          }   
        }   
    }       
    //==========================鼠标经过、离开节点的效果============================       
    with(TModuleNode){   
      mouseover(function(){   
        TNode_MouseOver($(this));   
      });   
         
      mouseout(function(){   
        TNode_MouseOut($(this));   
      });   
    }   
       
    with(TChildNode){   
      mouseover(function(){   
        TNode_MouseOver($(this));   
      });   
         
      mouseout(function(){   
        TNode_MouseOut($(this));   
      });   
    }   
       
    //-------------------------------(定义)----------------------------------   
    function TNode_MouseOver(Obj){   
      if(!(Obj.hasClass('show'))){   
          Obj.addClass('mouseOver');   
      }   
    }   
       
    function TNode_MouseOut(Obj){   
      Obj.removeClass('mouseOver');   
    }   
           
  //==========================编辑区操作============================       
    $('.editArea').each(function(){   
        EditArea_Event($(this));   
    });   
    //-------------------------------(定义)----------------------------------   
    function EditArea_Event(Obj){   
        var objParent = Obj.parent();  

        var objTitle = objParent.find('.title');//节点名称  
       //-----------------编辑区的鼠标效果------------------    
        Obj.children().each(function(){   
          with($(this)){   
              mouseover(function(){   
                $(this).addClass('mouseOver');   
              });   
              mouseout(function(){   
                $(this).removeClass('mouseOver');   
              });   
          }   
        });   
       //-------------------------------------------------    
        Obj.children().each(function(index, element) {   
            $(this).click(function(){
                if($('#TreeList').has('input').length==0){   
                    switch(index){   
                        case 0:    EditNode(objTitle,objTitle.html());break;//编辑   
                        case 1:    AddNode(0,objParent,NewNodeRename(0,objTitle));break;//添加同级目录   
                        case 2:    AddNode(1,objParent,NewNodeRename(1,objTitle));break;//添加下级目录   
                        case 3:    DelNode(objParent);break;//删除   
                    }   
                }   
                else{   
                    alert('请先取消编辑状态!');    
                }   
            });   
        });   
    }   
    //************************************************************************************************************   
    //************************************************************************************************************   
       
    //===============================验证编辑结果================================   
    function CheckEdititon(pNode,text){   
        var SameLevelTags    = new Array(PrentNodeClass,ChildNodeClass);   
        var SameLevelTag    = '';   
        for(var i=0;i<SameLevelTags.length;i++){   
            if(pNode.parent().attr('class').indexOf(SameLevelTags[i]) > -1){   
                SameLevelTag = SameLevelTags[i];   
                break;   
            }   
        }   
        if(SameLevelTag!=''){   
            if(text!=''){   
                //---------------- 根据节点样式遍历同级节点 --------------------   
                var IsExsit = false;   
                pNode.parent().parent().children('div').children('.title').each(function(){   
                    if(pNode.find('input').val()==$(this).html()){   
                        IsExsit = true;   
                        alert('抱歉!同级已有相同名称!');   
                        return false;   
                    }   
                });   
                return !IsExsit;   
            }   
             
          else{   
              alert('不能为空!');   
              return false;   
          }   
        }   
    }   
       
    //=================================自动命名================================   
    function NewNodeRename(tag,pNode){   
        //---------------- 根据节点样式遍历同级节点 --------------------   
        var MaxNum = 0;   
        var TObj;   
        if(tag==0){//添加同级目录   
            if(pNode.attr('id')==TreeName){   
                TObj = pNode.children('div').children('.title');   
            }   
            else{   
                TObj = pNode.parent().parent().children('div').children('.title');   
            }   
        }   
        else{//添加下级目录   
            if(pNode.parent().next().html()!=null){//原来已有子节点   
                TObj = pNode.parent().next().children('div').children('.title');   
            }   
            else{//没有子节点   
                TObj = null;   
            }   
        }   
           
        if(TObj){   
          TObj.each(function(){   
              var CurrStr = $(this).html();   
              var temp;   
              if(CurrStr.indexOf(NewNodeName)>-1){   
                  temp = parseInt(CurrStr.replace(NewNodeName,''));   
                  if(!isNaN(temp)){   
                      if(!(temp<MaxNum)){   
                          MaxNum = temp + 1;   
                      }   
                  }   
                  else{   
                    MaxNum = 1;     
                  }   
              }   
          });   
        }   
           
        var TempNewNodeName = NewNodeName;   
        if(MaxNum>0){   
            TempNewNodeName    += MaxNum;   
        }   
        return TempNewNodeName;   
    }   
       
    //=============================== 编辑定义 ================================   
    function EditNode(obj,text){
        obj.attr(Orititle,text);//将原来的text保存到Orititle中   
        obj.html("<input type='text' class=input value=" + text + "><input type='text' class=input value=路由>");//切换成编辑模式   
        obj.parent().find('.editBT').html("<div class=ok title=确定></div><div class=cannel title=取消></div>");   
        obj.has('input').children().first().focusEnd();//聚焦到编辑框内   
     
        obj.parent().find('.ok').click(function(){   
            Edit_OK(obj);   
        });   
           
        obj.parent().find('.cannel').click(function(){   
            Edit_Cannel(obj);   
        });   
    }   
       
    //=============================== 添加节点 ================================   
    function AddNode(tag,obj,NameStr){   
        if(tag==0 || tag==1){   
            // <div class='ChildNode'></div>
            var newNode = $('<div class=' + ChildNodeClass + '></div>');   
            if(tag==0){//添加同级目录   
                newNode.appendTo(obj.parent());   
            } else{//添加下级目录   
                if(!(obj.next()) || (obj.next().attr('class')!=ChildrenListClass)){//最后一个节点和class!=ChildrenListClass都表示没有子节点   
                    // <div class='Row'></div>
                    var ChildrenList = $('<div class=' + ChildrenListClass + '></div>');   
                    ChildrenList.insertAfter(obj);//将子节点的”外壳“加入到对象后面   
                    newNode.appendTo(ChildrenList);//将子节点加入到”外壳“内   
                } else {   
                    newNode.appendTo(obj.next());//将子节点加入到”外壳“内   
                }   
                obj.attr('class',PrentNodeClass + ' show');//激活父节点展开状态模式   
                obj.next().css('display','');//展开子节点列表   
            }   
             
            with(newNode){   
                html(EditHTML(NameStr));
                $('.judgeImg').unbind('click').click(function () {
                    if($(this).attr("src") == 'yes.png'){
                        $(this).attr('src','no.png');
                        $(this).parent().find('.title').attr('data-visible',0);
                    } else {
                        $(this).attr('src','yes.png');
                        $(this).parent().find('.title').attr('data-visible',1);
                    }
                }); 
                //---------------------------------动态添加事件-------------------------------   
                mouseover(function(){   
                    TNode_MouseOver($(this));   
                });   
                 
                mouseout(function(){   
                    TNode_MouseOut($(this));   
                });   
                 
                find('.title').click(function(){   
                    TModuleNodeName_Click($(this));   
                });   
                 
                find('.editArea').each(function(){   
                    EditArea_Event($(this));   
                });   
                //---------------------------------------------------------------------------   
            }   
            EditNode(newNode.find('.title'),newNode.find('.title').html());//添加后自动切换到编辑状态   
        }   
    }   
       
    //=============================== [删除]按钮 ================================   
    function DelNode(obj){   
        if(confirm('确定要删除吗?')){   
            var objParent = obj.parent();   
            var objChildren = obj.next('.Row');   
            obj.remove();//基于Jquery是利用析构函数,所以“删除”后其相关属性仍然存在,除非针对ID来操作就可以彻底删除   
            objChildren.remove();//删除对象所有子节点   
            ChangeParent(objParent);   
        }   
    }   
       
    //=============================== 编辑[确定]按钮 ================================   
    function Edit_OK(obj){   
        var tempText = obj.has('input').children().first().val();   
        var dataUrl = obj.has('input').children().first().next().val();// add@by amu 获取URL值
        if(CheckEdititon(obj,tempText)){   
            obj.html(tempText);   
        } else {   
            obj.html(obj.attr(Orititle));     
        }   
        obj.removeAttr(Orititle);
        obj.attr('data-url',dataUrl);// add@by amu 设置URL值
        obj.parent().find('.editBT').html('');   
    }   
       
    //=============================== 编辑[取消]按钮 ================================   
    function Edit_Cannel(obj){   
        obj.html(obj.attr(Orititle));   
        obj.removeAttr(Orititle);   
        obj.parent().find('.editBT').html('');   
    }   
       
    //=============================== 改变父节点样式 ================================   
    function ChangeParent(obj){   
        if(obj.find('.ChildNode').length==0){//没有子节点   
            obj.prev('.'+PrentNodeClass).attr('class',ChildNodeClass);   
            obj.remove();   
        }   
    }   
       
    //************************************************************************************************************   
    //************************************************************************************************************   
    //************************************************************************************************************   
       
    //=============================== 设置聚焦并使光标设置在文字最后 ================================   
    $.fn.setCursorPosition = function(position){     
        if(this.lengh == 0) return this;     
        return $(this).setSelection(position, position);     
    }     
         
    $.fn.setSelection = function(selectionStart, selectionEnd) {     
        if(this.lengh == 0) return this;     
        input = this[0];     
         
        if (input.createTextRange) {   
            var range = input.createTextRange();     
            range.collapse(true);    
            range.moveEnd('character', selectionEnd);     
            range.moveStart('character', selectionStart);     
            range.select();    
        } else if (input.setSelectionRange) {     
            input.focus();    
            input.setSelectionRange(selectionStart, selectionEnd);     
        }     
        return this;     
    }     
         
    $.fn.focusEnd = function(){   
        this.setCursorPosition(this.val().length);     
    }   
       
    //=========================================================================================   
       
});   
</script>
</head>
<body>     
    <div id="TreeList">   
        <div class="ParentNode show">   
            <div class="title" data-visible='1' data-url='/Ku/zhan'>系统设置</div>   
            <div class="editBT"></div>
            <img src="yes.png" alt="" class="judgeImg" />
            <div class="editArea"><span>[编辑]</span><span>[添加同级目录]</span><span>[添加下级目录]</span><span>[删除]</span></div>   
        </div>   
        <div class="Row">   
            <div class="ChildNode">   
                <div class="title" data-visible='0' data-url='/Ou/mei'>用户管理</div>   
                <div class="editBT"></div>
                <img src="no.png" alt="" class="judgeImg" />
                <div class="editArea"><span>[编辑]</span><span>[添加同级目录]</span><span>[添加下级目录]</span><span>[删除]</span></div>   
            </div>   
            <div class="ChildNode">   
                <div class="title" data-visible='1' data-url='/Ri/han'>角色管理</div>   
                <div class="editBT"></div>   
                <img src="yes.png" alt="" class="judgeImg" />
                <div class="editArea"><span>[编辑]</span><span>[添加同级目录]</span><span>[添加下级目录]</span><span>[删除]</span></div>   
            </div>
        </div>
    </div>
</body>
<script>
    $('.judgeImg').unbind('click').click(function () {
        if($(this).attr("src") == 'yes.png'){
            $(this).attr('src','no.png');
            $(this).parent().find('.title').attr('data-visible',0);
        } else {
            $(this).attr('src','yes.png');
            $(this).parent().find('.title').attr('data-visible',1);
        }
    });
</script>   
</html>  

效果展示

image.png
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,539评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,911评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,337评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,723评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,795评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,762评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,742评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,508评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,954评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,247评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,404评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,104评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,736评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,352评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,557评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,371评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,292评论 2 352

推荐阅读更多精彩内容

  • 1、通过CocoaPods安装项目名称项目信息 AFNetworking网络请求组件 FMDB本地数据库组件 SD...
    阳明先生_X自主阅读 15,979评论 3 119
  • 又到一年公考季,再过两天即将迎来2017年国家公务员考试,千万刚毕业的莘莘学子,千军万马过独木河的场景又将一一呈现...
    河对岸的窗阅读 436评论 0 1
  • 橘红,走过凌晨两点的十二道白。 斑马线留不住慌张,也留不住虚伪的温热。 还会有人此刻到来,摆脱清晨与黄昏,恰到好处...
    剪刀手瓦力阅读 120评论 0 2
  • 仗剑任侠家万里,生死须臾志不移。 天下不平天下事,何愁人生无归期。
    可以轩主人阅读 142评论 2 1