我爱编程

js树状目录

2018-06-10  本文已影响20人  7730699b0e49

页面效果


js树状目录.png

js

//定义树节点
function Node(id,pid,name,icon,iconOpen,open){
    this.id = id;               //该节点的id
    this.pid = pid;             //该节点的父id
    this.name = name;           //该节点显示的名字
    this.icon = icon;           //该节点未展开时的图标
    this.iconOpen = iconOpen;   //该节点展开时的图标
    this.co = open || false;    //该节点是否展开(close/open),默认是false
    this.last = false;          //该节点是否是同级节点中最后一个,用来判断返回递归的上一层
    this.hc = false;            //该节点是否含有孩子节点(hasChild)
    this.index = 0;             //该节点在全局数组中的下标
    this.parent;                //该节点的父节点
}
//定义树对象
function Tree(objName){
    //配置
    this.config={
            useIcons:   false,  //文件夹图标
            useLines:   false,  //缩进线
            checkbox:   false,  //复选框
            checkName:  objName //复选框的name,默认是对象名
    };
    //图标
    this.icon = {
            root:   'img/base.gif',
            floder: 'img/folder.gif',
            floderOpen:'img/folderopen.gif',
            node:   'img/page.gif',
            line:   'img/line.gif',
            empty:  'img/empty.gif',
            nlMinus:'img/nolines_minus.gif',    //无线的-号
            nlPlus: 'img/nolines_plus.gif',     //无线的+号
            minusBottom:'img/minusbottom.gif',
            plusBottom: 'img/plusbottom.gif',
            minus:  'img/minus.gif',
            plus:   'img/plus.gif',
            join:   'img/join.gif',
            joinBottom: 'img/joinbottom.gif'
    }
    this.obj = objName;         //当前对象名字,通过这个名字生成id
    this.nodes = new Array();   //保存树节点的数组
    this.root = new Node(-1);   //根节点
    this.indent = new Array();  //缩进的个数
}
//添加一个节点对象
Tree.prototype.add = function(id,pid,name,icon,iconOpen,open){
    //把节点存入数组中
    this.nodes[this.nodes.length] = new Node(id,pid,name,icon,iconOpen,open);
}
//当执行document.write(Tree的对象)语句时会执行toString函数
Tree.prototype.toString = function(){
    var str = '<div class="dtree">\n';
    str += this.addNode(this.root);
    str += '</div>';
    return str;
}
//添加一个节点
Tree.prototype.addNode = function(pNode){
    var str = '';   //拼接html的字符串
    var n = 0;      //下标
    for(n;n<this.nodes.length;n++){
        if(this.nodes[n].pid == pNode.id){  //找到当前节点的子节点进行处理
            var cn = this.nodes[n]; //把找到的子节点赋给cn(childNode)
            cn.parent = pNode;  //设置该节点的父节点
            cn.index = n;   //设置该节点的数组下标
            this.setHc(cn); //设置该节点是否含有子节点
            str += this.node(cn,n); //拼接树
            if(cn.last){    //如果当前节点是最后一个节点,则返回上一层递归
                break;
            }
        }
    }
    return str;
}
//查看当前节点是否含有子节点
Tree.prototype.setHc = function(node){
    var lastId; 
    for(var n=0;n<this.nodes.length;n++){
        if(node.id == this.nodes[n].pid){ //如果有子节点,设置成true
            node.hc = true;
        }
        if(node.pid == this.nodes[n].pid){  //
            lastId = this.nodes[n].id;
        }
    }
    if(node.id == lastId){  //当前节点是否是同级节点中最后一个节点
        node.last = true;   
    }
}
//
Tree.prototype.node = function(node,n){
    var str = '<div class="dtreeNode">' + this.getIndent(node,n);   //第一次getIndent是空的,用空白图片占位来缩进
    if(this.config.useIcons){
        if(!node.icon){ //没展开时图标
            node.icon = (node.hc) ? this.icon.floder : this.icon.node;
        }
        if(!node.iconOpen){ //展开时图标
            node.iconOpen = (node.hc) ? this.icon.floderOpen : this.icon.node;
        }
        if(node.pid == this.root.id){   //根节点的图标
            node.icon = this.icon.floder;
            node.iconOpen = this.icon.floder;
        }
        //判断根据node.cn的设置来使用图标
        str += '<img id="i'+ this.obj + n +'" src="'+((node.co) ? node.iconOpen : node.icon)+'" alt="" />';
    }
    if(this.config.checkbox){   //是否有复选框
        str += '<input type="checkbox" id="c'+this.obj + node.id +'" value="'+node.id+'" name="'+this.config.checkName+'" onclick="'+this.obj+'.clickCheckbox('+node.id+','+node.pid+');" style="vertical-align:middle"/>';
    }
    str += node.name;   //节点的名字
    str += '</div>';
    //判断有没有子节点,如果有则递归调用addNode,把一个节点的所有子节点处理完再处理其他节点
    if(node.hc){
        str += '<div id="d'+ this.obj + n +'" class="clip" style="display:'+((this.root.id == node.pid || node.co)?'block':'none')+'">';
        str += this.addNode(node);
        str += '</div>';
    }
    this.indent.pop();  //返回一层,删除一个数组元素
    return str;
}
//节点的缩进
Tree.prototype.getIndent = function(node,nodeId){
    var str = '';
    if(this.root.id != node.pid){   //判断当前节点的是否是根节点的子节点,如果是,则没有缩进
        for(var n=0;n<this.indent.length;n++){
            str += '<img src="'+((this.indent[n] == 1 && this.config.useLines) ? this.icon.line : this.icon.empty)+'"/>'
        }
        (node.last) ? this.indent.push(0) : this.indent.push(1);    //递归一层,添加一个数组元素,用来识别使用几个缩进
        if(node.hc){    //是否有子节点
            str += '<a href="javascript:'+ this.obj +'.toggle('+ nodeId +');"><img id="j'+ this.obj + nodeId +'" src="';
            if(!this.config.useLines){
                str += (node.co) ? this.icon.nlMinus : this.icon.nlPlus;
            }else{
                str += ((node.co) ? ((node.last) ? this.icon.minusBottom : this.icon.minus) : ((node.last) ? this.icon.plusBottom : this.icon.plus));
            }
            str += '" alt="" /></a>';
        }else{
            str += '<img src="' + ((this.config.useLines) ? ((node.last) ? this.icon.joinBottom : this.icon.join) : this.icon.empty) + '" alt="" />';
        }
    }
    return str;
}
//展开或关闭节点
Tree.prototype.toggle = function(id){
    var cn = this.nodes[id];
    this.nodeStatus(!cn.co,id,cn.last);
    cn.co = !cn.co; //修改co的状态
}
//修改展开和关闭状态的图标
Tree.prototype.nodeStatus = function(co,id,last) {
    var eDiv = document.getElementById("d" + this.obj + id);    //一个节点div对象
    var eJion = document.getElementById("j" + this.obj + id);   //加减号img对象
    if(this.config.useIcons){
        eIcon = document.getElementById('i' + this.obj + id);   //文件夹图标img对象
        eIcon.src = (co) ? this.nodes[id].iconOpen : this.nodes[id].icon;
    }
    //先判断用不用线,要是用线的话,并且是同级最后一个节点,则没有下边的线
    eJion.src = (this.config.useLines) ? 
        ((co)?((last)?this.icon.minusBottom:this.icon.minus):((last)?this.icon.plusBottom:this.icon.plus)) :
        ((co)?this.icon.nlMinus:this.icon.nlPlus);
    eDiv.style.display = (co) ? 'block' : 'none';   //节点的div标签显示或关闭
}
//点击复选框事件
Tree.prototype.clickCheckbox = function(id,pid){
    var bo = document.getElementById("c"+this.obj+id);  //多选框对象
    for(var i=0;i<this.nodes.length;i++){
        if(this.nodes[i].pid == id){    //把当前节点的子节点选中或取消
            document.getElementById("c"+this.obj+this.nodes[i].id).checked = bo.checked;
            this.clickCheckbox(this.nodes[i].id,this.nodes[i].pid); //递归调用
        }
    }
}

html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>js树状目录</title>
<link type="text/css" rel="stylesheet" href="dtree.css"/>
<script type="text/javascript" src="shztree.js"></script>
</head>
<body>
    <h2>树</h2>
    <input type="button" id="btn" value="提交"/>
    <script>
        var tree = new Tree("tree");
        tree.add(0,-1,'My root tree');
        tree.add(1,0,'Node 1');
        tree.add(2,0,'Node 2');
        tree.add(3,1,'Node 1.1');
        tree.add(4,3,'Node 1.1.1');
        tree.add(5,2,'Node 2.1');
        tree.add(6,2,'Node 2.2');
        tree.add(7,0,'Node 3');
        tree.add(8,7,'Node 3.1');
        tree.add(9,3,'Node 1.1.2');
        /* for(var i=0;i<array.length;i++){ //从后台传过来一个array
            tree.add(array[i].id,array[i].pid,array[i].name);
        } */
        tree.config.useLines = true;
        tree.config.checkbox = true;
        tree.config.useIcons = true;
        document.write(tree);
        
        document.getElementById("btn").onclick = function(){
            var check = document.getElementsByName("tree");
            var idsTmp = '';
            for(var i=0;i<check.length;i++){
                if(check[i].checked == true){
                    idsTmp = idsTmp + check[i].value +",";
                }
            }
            var ids = idsTmp.substr(0,idsTmp.length-1);
            alert(ids);
        }
    </script>
</body>
</html>

css

.dtree {
    font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;
    font-size: 11px;
    color: #666;
    white-space: nowrap;
}
.dtree img {
    border: 0px;
    vertical-align: middle;
}
.dtree a {
    color: #333;
    text-decoration: none;
}
.dtree a.node, .dtree a.nodeSel {
    white-space: nowrap;
    padding: 1px 2px 1px 2px;
}
.dtree a.node:hover, .dtree a.nodeSel:hover {
    color: #333;
    text-decoration: underline;
}
.dtree a.nodeSel {
    background-color: #c0d2ec;
}
.dtree .clip {
    overflow: hidden;
}
上一篇下一篇

猜你喜欢

热点阅读