zoukankan      html  css  js  c++  java
  • 我的JS树(2)

    在第一篇完成了树的基本展示后,终于有时间接着来完善用户交互部分了。这个版本的代码添加了

         1.展开/折叠功能,

         2.点击节点时触发相应事件

         如下:

    计算机
    编程语言
    C语言
    C语言程序设计
    C#语言
    设计模式
    数学
    社会学

          <script type="text/javascript">

            var Tree =
        {
            Resources:
            {
                Images:
                {
                    TrunkNode:
                    {
                        Expanded: 
    "folder-open.gif",
                        Collapsed: 
    "folder.gif"
                    },
                    LeafNode: 
    "leaf.gif",
                    Lines:
                    {
                        Elbow: 
    "elbow.gif",
                        ElbowEnd: 
    "elbow-end.gif",
                        ElbowLine: 
    "elbow-line.gif",
                        Blank: 
    "blank.gif"
                    }

                }
            },
            Styles:
            {
                NodeHeight: 
    "16px"
            },
            Settings:
            {
                
    ///<summary>
                ///点击节点时触发
                ///</summary>
                OnNodeClick: function(node) {
                    alert(node.innerText 
    || node.textContent);
                },
                Expanded: 
    false
            },
            
    ///<summary>
            ///创建树
            ///<param name='nodes'>初始要加载的节点(节点的数组,可以使用js字面量也可以用数组:[{"ID":"1", "Name":"Node"}])</param>
            ///</summary>
            BuildTree: function(nodes, parentNode) {
                
    if (nodes && nodes.length > 0) {
                    
    //Level 1
                    for (var i = 0; i < nodes.length; i++) {
                        
    var oNode = this._BuildNode(nodes[i], (i == nodes.length - 1? true : false, parentNode, this.Settings.Expanded);
                        
    this._Fragment.appendChild(oNode);
                        
    if (nodes[i].HasChild)//如果有子节点
                        {
                            
    var childNodes = nodes[i].ChildNodes;
                            
    this.BuildTree(childNodes, oNode);
                        }

                    }
                }
                
    this._InitEvent();
            },
            
            
    ///<summary>
            ///创建节点
            ///<param name="node">节点对象(可以是js字面量,也可以是一般的对象)</param>
            ///<param name="isLast">判断节点是否为同级的最后一个</param>
            ///<param name="parentNode">父节点</param>
            ///</summary>
            _BuildNode: function(node, isLast, parentNode, expanded) {
                
    if (node) {
                    
    var oNode = document.createElement("div");
                    oNode.style.height 
    = this.Styles.NodeHeight;

                    
    var t = this;

                    
    if (node.HasChild) {
                        oNode.style.cursor 
    = "pointer";
                    }

                    
    if (parentNode) {
                        oNode.style.display 
    = expanded ? "" : "none";
                    }

                    
    //节点的完整路径,存储从最上层的节点一直到本节点的Index,是为了方便按照level来寻找节点对应level的祖先节点
                    var nodePath = new Array();

                    
    if (parentNode && parentNode.NodePath && parentNode.NodePath.length > 0) {
                        
    for (var i = 0; i <= parentNode.NodePath.length - 1; i++) {
                            nodePath.push(parentNode.NodePath[i]);
                        }

                    }
                    nodePath.push(t._Index);
                    oNode.NodePath 
    = nodePath;

                    oNode.innerText 
    = oNode.textContent = "";
                    
    //构造相对于父节点的连接线
                    for (var i = 1; i < node.Level; i++) {
                        
    var ancestorNode = t._Nodes[nodePath[i - 1]];
                        
    var oImg = document.createElement("img");

                        oImg.src 
    = ancestorNode.IsLast ? t.Resources.Images.Lines.Blank : t.Resources.Images.Lines.ElbowLine;
                        oNode.appendChild(oImg);
                    }

                    
    //构造节点本身的连接线
                    var elbowImg = document.createElement("img");
                    
    var elbowImgUrl = t.Resources.Images.Lines.Elbow;
                    
    if (isLast)//是同级的最后一个节点,则添加elbow-end.gif
                    {
                        elbowImgUrl 
    = t.Resources.Images.Lines.ElbowEnd;
                    }
                    elbowImg.src 
    = elbowImgUrl;
                    oNode.appendChild(elbowImg);

                    
    //构造节点类型图片
                    var imgUrl = t.Resources.Images.TrunkNode.Collapsed;
                    
    if (node.IsLeaf) {
                        imgUrl 
    = t.Resources.Images.LeafNode;
                    }
                    
    var nodeTypeImg = document.createElement("img");
                    nodeTypeImg.src 
    = imgUrl;
                    nodeTypeImg.NodeTypeImg 
    = true;
                    oNode.appendChild(nodeTypeImg);

                    
    //节点名字
                    var oSpan = document.createElement("span");
                    oSpan.innerText 
    = node.Name;
                    oSpan.textContent 
    = node.Name;
                    oSpan.Name 
    = true;
                    oNode.appendChild(oSpan);

                    oNode.Index 
    = t._Index;
                    oNode.ParentNodeIndex 
    = parentNode ? parentNode.Index : null;
                    oNode.IsLast 
    = isLast;
                    oNode.IsLeaf 
    = node.IsLeaf;
                    oNode.Level 
    = node.Level;
                    oNode.Expanded 
    = expanded;

                    t._Nodes[t._Index] 
    = oNode;
                    t._Index
    ++;


                    
    return oNode;
                }

            },
            
    ///<summary>
            ///初始化节点的事件处理程序
            ///</summary>
            _InitEvent: function() {
                
    var t = this;
                
    for (var i = 1; i < t._Nodes.length; i++) {
                    
    var node = t._Nodes[i];
                    
    for (var j = 0; j < node.childNodes.length; j++) {
                        
    if (node.childNodes[j].NodeTypeImg) {
                            node.childNodes[j].onclick 
    = function() {
                                
    var parentNode = this.parentNode;
                                
    var childNodes;
                                
    if (parentNode.Expanded) {//当前是展开的,需要隐藏后代节点
                                    childNodes = t._FindDescendantNodes(parentNode);
                                }
                                
    else {//当前是收缩的,只需展开子节点即可
                                    childNodes = t._FindChildNodes(parentNode);
                                }
                                
    for (var k = 0; k < childNodes.length; k++) {
                                    childNodes[k].style.display 
    = parentNode.Expanded ? "none" : "";
                                }
                                parentNode.Expanded 
    = !parentNode.Expanded;
                            }
                        }
                        
    else if (node.childNodes[j].Name) {
                            node.childNodes[j].onclick 
    =
                            
    function() {
                            t.Settings.OnNodeClick.call(
    thisthis);
                            }
                        }
                    }

                }

            },
            _Index: 
    1,
            _Fragment: document.createDocumentFragment(),
            _Nodes: 
    new Array(),
            
    ///<summary>
            ///寻找节点子节点
            ///</summary>
            _FindChildNodes: function(node) {
                
    var result = [];
                
    if (this._Nodes.length > 0) {
                    
    for (var i = 1; i < this._Nodes.length; i++) {
                        
    if (this._Nodes[i].ParentNodeIndex == node.Index) {
                            result.push(
    this._Nodes[i]);
                        }
                    }
                    
    return result;
                }
            },
            
    ///<summary>
            ///寻找后代节点
            ///</summary>
            _FindDescendantNodes: function(node) {
                
    var result = [];
                
    if (this._Nodes.length > 0) {
                    
    for (var i = 1; i < this._Nodes.length; i++) {
                        
    if (this._Nodes[i].NodePath.join(",").indexOf(node.NodePath.join(",")) == 0 && this._Nodes[i] != node) {
                            result.push(
    this._Nodes[i]);
                        }
                    }
                    
    return result;
                }
            }
        }
        
    </script>
  • 相关阅读:
    day 13 闭包函数,装饰器,迭代器
    day12 可变长参数、函数对象、函数的嵌套、名称空间和作用域
    day11 文件的高级应用、文件修改的两种方式、函数的定义、函数的三种定义方式、函数的调用、函数的返回值、函数的参数
    数字类型内置方法
    基本语法之for循环
    基本语法之while循环
    python基本语法(3)
    python基本语法(2)
    python基本语法(1)
    编程及计算机组成
  • 原文地址:https://www.cnblogs.com/jcomet/p/1693614.html
Copyright © 2011-2022 走看看