`
pcajax
  • 浏览: 2107173 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

js 树菜单

阅读更多

 
<!doctype html>
<title>树 by 司徒正美</title>
<meta charset="utf-8"/>
<meta name="keywords" content="树 by 司徒正美" />
<meta name="description" content="树 by 司徒正美" />
<h2>树 by 司徒正美</h2>
<script type="text/javascript">
  Tree = function(){
    this.path = "http://images.cnblogs.com/cnblogs_com/rubylouvre/205314/o_";
    this.name = "tree";
    this.id = + new Date + parseInt(Math.random()*100000);
    this.initialize.apply(this, arguments);
  }
  Tree.prototype = {
    constructor : Tree,
    initialize : function(config){
      var me = this, renderTo = config.renderTo;
      me.tree = config.data;
      me.container = ((typeof renderTo === "string") ?
        document.getElementById(renderTo) : renderTo) || document.body;
      me.panel = document.createElement("div");
      me.panel.setAttribute("id","tree" + me.id)
      me.container.insertBefore(me.panel,null);
      var id = "#"+me.panel.id;

      var sheet = document.createElement('style');
      sheet.type = 'text/css';
      document.getElementsByTagName('head')[0].appendChild(sheet);
      var bg = "background:transparent url("+me.path;
      var cssCode = id +" {font-size:12px;}\n" +
        id+" img {border:0;vertical-align: middle;}\n" +
        id+" span {vertical-align: bottom;}\n"+
        id+" .line {padding-left:18px;"+bg+"line.gif) repeat-y 0 0;}\n"+
        id+" .blank {margin-left:18px;}\n"+
        id+" img.collapse {padding-right:18px;"+bg+"folder.gif) no-repeat right center;}\n"+//控制枝节点的装饰图标(闭合)
      id+" img.unfold {padding-right:18px;"+bg+"folderopen.gif) no-repeat right center;}\n"+//控制枝节点的装饰图标(展开)
      id+" img.root {padding-right:18px;"+bg+"root.gif) no-repeat right center;}\n"+ //控制根节点的装饰图标
      id+" img.leaf {padding-right:18px;"+bg+"leaf.gif) no-repeat right center;}\n" //控制叶节点的装饰图标
      if(!+"\v1"){
        sheet.styleSheet.cssText = cssCode
      }else if(/a/[-1]=='a'){
        sheet.innerHTML = cssCode
      }else{
        sheet.appendChild(document.createTextNode(cssCode));
      }

      //添加根节点
      var icon = me.makeImage("nolines_plus","collapse root")
      var checkbox0 = me.makeImage("checkbox_0","checkbox_0");
      me.panel.innerHTML = me.makeTree(me.tree[0][0],"b",0,icon+checkbox0, me.tree[0][2]);
      me.childs = [];
      me.checks = [];//由来装载点击数
      me.panel.onclick = function(e){
        e = e || window.event;
        var node = e.srcElement ? e.srcElement : e.target;
        var current = node.parentNode;
        var currentIndex = current.getAttribute("index");
        var currentPrefix = current.getAttribute("prefix");
        var currentLevel = current.getAttribute("level");
        var subtree = me.getSubtree(currentIndex);
        var children = current.children[3];
        //添加子树集合
        //存在子树并且没有添加时才添加
        if(subtree && !children){
          children = document.createElement("div");
          var childs = [];
          for(var i=0,length = subtree.length;i<length;i++){
            var isLimb = me.hasSubtree(subtree[i][0]);
            var isLast = (i == subtree.length - 1);
            var prefix = isLast ? "blank" : "line";
            icon = isLast ? "plusbottom" : "plus";
            if(isLimb){
              icon = me.makeImage(icon,"collapse limb");//枝节点前面的装饰图标
            }else{
              icon = icon.replace(/plus/, "join");//叶子节点前面的连线图标
              icon = me.makeImage(icon,"leaf");//叶子节点前面的装饰图标
            }
            childs.push(subtree[i][0])
            children.innerHTML += me.makeTree(subtree[i][0],prefix,+currentLevel+1,icon+checkbox0,subtree[i][2])
          }
          me.childs[currentIndex] = childs;
          children.className = (currentPrefix == "line") ? "line": "blank";
          current.insertBefore(children,null);
        }

        if(/collapse/.test(node.className)){//如果点击是加号或减号图标
          node.src = node.src.replace(/plus/,"minus");//改变连线图标
          node.className = node.className.replace("collapse","unfold");//改变装饰图标
          children &&(children.style.display = "block");
        }else if(/unfold/.test(node.className)){
          node.src = node.src.replace(/minus/,"plus");//改变连线图标
          node.className = node.className.replace("unfold","collapse");//改变装饰图标
          children &&(children.style.display = "none");
        }

        if(/checkbox/.test(node.className)){//如果单击的是checkbox图标
          var checked = me.isChecked(node);//如果是true则--,如果是false则++
          me.setPriorCheckbox(current,checked);//一开始肯定是checkbox,返回false
          me.setJuniorCheckbox(current,checked)
        }
      }
    },
    setJuniorCheckbox : function(node,/*Boolean*/checked){
      var checkbox = node.children[1];
      var replaceCheckbox = checked ? "checkbox_0" :"checkbox_1";
      checkbox.src = checkbox.src.replace(/checkbox_\d/,replaceCheckbox);
      checkbox.className  = replaceCheckbox;
      var index = node.getAttribute("index");
      if(!!this.childs[index]){
        var length = this.childs[index].length;
        this.checks[index] = checked ? length : 0;
        if(length > 0){
          var children = node.children[3].children;
          while(--length >= 0){
            this.setJuniorCheckbox(children[length],checked)
          }
        }
      }
    },
    setPriorCheckbox :function(node,/*Boolean*/checked){//设置上一级树的checkbox
      var index = node.getAttribute("index");
      var prior = node.parentNode.parentNode;
      var priorIndex = this.tree[index][1];
      var priorCheckbox = prior.children[1];
      var priorLevel = prior.getAttribute("level");
      var priorCount = this.checks[priorIndex] || 0;
      checked ? priorCount-- : priorCount++;
      (priorCount < 0) && (priorCount = 0)
      this.checks[priorIndex] = priorCount;
      if(!!priorCheckbox){
        //当priorIndex等于-1时,
        //priorCheckbox不存在
        //me.childs[priorIndex]为undefined,不存在长度
        checked = (priorCount == this.childs[priorIndex].length);
        var replaceCheckbox = checked ? "checkbox_1" : "checkbox_2";
        //checkbox_1为全选,checkbox_2为非全选
        //全选,则让上级++,即让checked为false
        priorCheckbox.src =  priorCheckbox.src.replace(/checkbox_\d/,replaceCheckbox);//????????
        priorCheckbox.className  = replaceCheckbox;
      }
      if(priorLevel > 0){ //根节点没有priorCheckbox,且priorLevel等于-1
        this.setPriorCheckbox(prior,checked);
      }
    },
    isChecked : function(node){//如果是checkbox_0返回false,checkbox_1与checkbox_2返回true
      return node.src.slice(-5,-4) > 0;
    },
    makeImage : function(image){
      var status ="";
      if(arguments[1] != null){
        status = "class='" + arguments[1] +"'";
      }
      return "<img src='"+this.path+image+".gif' "+status+" />"
    },

    makeTree : function(index,prefix,level,images,text){
      var builder = [];
      builder.push("<div index='");
      builder.push(index);
      builder.push("' prefix='")
      builder.push(prefix);
      builder.push("' level='")
      builder.push(level);
      builder.push("'>");
      builder.push(images);
      builder.push("<span>");
      builder.push(text);
      builder.push("</span></div>")
      return builder.join('');
    },
    hasSubtree : function (p){
      var tree = this.tree;
      for(var i = 0,length = tree.length;i < length; i++){
        if(this.tree[i][1] == p){
          return true;
        };
      };
      return false;
    },
    getSubtree : function (p){
      var subtree = [],tree = this.tree;
      for(var i = 0,length = tree.length;i < length; i++){
        if(tree[i][1] == p){
          subtree.push(tree[i]);
        };
      };
      return subtree
    }
  }

  var data = [
    [0,-1,"前台技术"],
    [1,0,"表现层"],
    [2,1,"CSS"],
    [3,2,"CSS资源"],
    [4,2,"CSS3前瞻"],
    [5,1,"web标准知识"],
    [6,1,"图形"],
    [7,6,"SVG"],
    [8,6,"VML"],
    [9,6,"canvas"],
    [10,0,"结构层"],
    [11,10,"HTML"],
    [12,10,"微格式"],
    [13,10,"XML"],
    [14,13,"XPath"],
    [15,0,"行为层"],
    [16,15,"core"],
    [17,16,"变量与参数"],
    [18,16,"对象与继承"],
    [19,16,"函数与闭包"],
    [20,16,"算法"],
    [21,16,"高级技术"],
    [22,21,"跨域请求"],
    [23,21,"提速技术"],
    [24,21,"本地存储"],
    [25,21,"函数劫持"],
    [26,16,"框架设计"],
    [27,26,"Ext"],
    [28,26,"dojo"],
    [29,26,"mootools"],
    [30,15,"Ajax"],
    [31,15,"DOM"],
    [32,15,"BOM"]
  ]

  window.onload = function(){
    var tree = new Tree({renderTo:"test",data:data});
  }

</script>
<div id="test"></div>

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics