js树状目录

作者: 7730699b0e49 | 来源:发表于2018-06-10 21:12 被阅读20次

    页面效果


    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;
    }

    相关文章

      网友评论

        本文标题:js树状目录

        本文链接:https://www.haomeiwen.com/subject/owyqeftx.html