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树状目录

    页面效果 js html css

  • 鸟哥私房菜第三章习题

    1、Linux的目录配置以“树状目录”来配置,至于磁盘分区(partition)则需要与树状目录相配合!请问,在默...

  • linux学习100篇57:tree -L 1

    tree树状图列出目录的内容 补充说明tree命令 以树状图列出目录的内容。 语法tree(选项)(参数)选项--...

  • tree [options]

    列出目录树状图 options -a 列出所有文件-d 仅列出目录-i 不打印出树状结构符号-C/-n 打开/关闭...

  • linux目录结构详细介绍

    linux目录结构详细介绍 目录 [1、树状目录结构图] [2、/目录] [3、/etc/目录] [4、/usr/...

  • linux 技术学习笔记(转载)

    目录文件结构: 树状目录结构: 目录结构的解释: /bin: bin是Binnary的缩写,这个目录存放着最常使用...

  • Linux命令之tree(3)

    tree命令的功能是用于以树状图形式列出目录内容,帮助开发人员快速了解到目录的层级关系 1、功能说明 用于以树状图...

  • easyui的tree学习

    目的:实现一个公共的组织结构树状图。效果图: 此树状图作为公共功能被调用。 此树状图不能被其他控件所遮挡。 目录结...

  • Linux 文件与目录管理

    Linux 文件与目录管理 我们知道Linux的目录结构为树状结构,最顶级的目录为根目录 /。 其他目录通过挂载...

  • linux之two

    Linux 文件与目录管理 我们知道Linux的目录结构为树状结构,最顶级的目录为根目录 /。 其他目录通过挂载可...

网友评论

    本文标题:js树状目录

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