⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 treemenu.htm

📁 JavaScript常用的特效
💻 HTM
字号:
<!---
  简单的树形菜单

  

  树形菜单较滑动菜单稍微复杂一点。其主要难点在于从简洁的数据描述来产生便于操纵的html结构。
  本例用来展示树形菜单的编写。使用无线表格,算法上采用了递归,理论上可构造无穷分制枝的树。
  本代码可自由扩散。
--->
<style>
table {font-size = 9pt}
td {height = 10px}
</style>
<body>
<span id="menus"></span>
<span id="view"></span>
</body>

<script>

var openfolder="<image src='images\\openfolder.gif'>";
var openfolder_fst="<image src='images\\openfolder_fst.gif'>";
var openfolder_end="<image src='images\\openfolder_end.gif'>";
var closefolder_fst="<image src='images\\closefolder_fst.gif'>";
var closefolder_end="<image src='images\\closefolder_end.gif'>";
var closefolder="<image src='images\\closefolder.gif'>";
var leafnode_end="<image src='images\\leafnode_end.gif'>";
var leafnode="<image src='images\\leafnode.gif'>";

/**
* 构造树,初值为0
*/
function tree(n) {
    
    var id = new Array("bar","pad",openfolder,closefolder);
    if(n == 0) { // 初始化变量
        n = 1;
        i = 0; //变量i用于表示当前行
        s = "";
    }
  
    s += "<table >";
    for(;i<tree_ar.length-1;i++) {
        var k = (n >= tree_ar[i+1][0])?0:1;   //当前层数大于下一行的层数,需显示叶子节点(k=0),否则是文件夹(k=1)
        
        if(n > tree_ar[i+1][0])// 若下一节点层次小于当前层次,叶子节点,结束本层次返回上一层次
        {
          
          s += "<tr id='"+id[k]+"' value="+i+"><td>"+leafnode_end+"</td><td>"+tree_ar[i][1]+"</td></tr>"; 
          s += "</td></tr></table>";
          return tree_ar[i+1][0];   //返回下一节点的层数
        }
        else if(n == tree_ar[i+1][0])// 若下一节点层次等于当前层次,叶子节点
        {
           
           if(tree_ar[i+1][1]=="")  //最后一个节点
            s += "<tr id='"+id[k]+"' value="+i+"><td>"+leafnode_end+"</td><td>"+tree_ar[i][1]+"</td></tr>"; 
           else
           s += "<tr id='"+id[k]+"' value="+i+"><td style=\"background:url(line_y.gif) repeat-y 7px 0\">"+leafnode+"</td><td>"+tree_ar[i][1]+"</td></tr>";           
        }
        else // 若下一节点层次大于当前层次,递归进入下一层次,非叶子节点。
        {
            // 构造节点,注意这里的自定义属性value。作用是简化构造节点的描述,共享参数数组信息。
           if(i==0 && k==1)  //第一行非叶子节点
            {              
              s += "<tr id='firstfolder' value="+i+"><td>"+closefolder_fst+"</td><td>"+tree_ar[i][1]+"</td></tr>"; 

   s += "<tr style='display:none'   v=1>"+
"<td style=\"background:url(images\\line_y.gif) repeat-y 7px 0\"></td><td>";

            }
          else
            {
           
               if(HasEqualLevel(i))
                 { s += "<tr id='"+id[k]+"' value="+i+"><td>"+id[k+2]+"</td><td>"+tree_ar[i][1]+"</td></tr>"; 
 
    s += "<tr style='display:none'   v=1>"+
"<td style=\"background:url(images\\line_y.gif) repeat-y 7px 0\"></td><td>";
                 }

               else
                 {
                  s += "<tr id='endfolder' value="+i+"><td>"+closefolder_end+"</td><td>"+tree_ar[i][1]+"</td></tr>";  
 s += "<tr style='display:none'   v=1>"+
"<td></td><td>";
    
                 }              
           
            }  
         
        
     


        var m = tree(tree_ar[++i][0]);
        s += "</td></tr>";

        // 当递归返回值小于当前层次期望值时,将产生连续的返回动作。
        if(m < n) 
            { 
                s += "</table>";
            //alert(tree_ar[i][1]);    
                return m;
 
            }

        
        }

        
    }
    s += "</table>";
   
    return s;
}

function HasEqualLevel(level)
{

  for(j=level+1;j<tree_ar.length-1;j++) 
  {
   if(tree_ar[j][0]==tree_ar[level][0])
    {
    
    return true;
    }
  }
return false;
}
</script>


<script for=firstfolder event=onclick>
// 分枝节点的点击响应,根节点

v = this.parentElement.rows[this.rowIndex+1].style;
if(v.display == 'block') {
    v.display = 'none';
    this.cells[0].innerHTML = closefolder_fst;
    view.innerHTML = ""; // 自行修改为参数数组定义的闭合动作
}
else 
{
    v.display = 'block';
    this.cells[0].innerHTML = openfolder_fst;
    view.innerHTML = "<b>"+tree_ar[this.value][1]+"</b>"; // 自行修改为参数数组定义的展开动作
}

/**
* 以下代码用于关闭已展开的其他分枝
* 如需自行关闭展开的分枝则从这里直接返回或删去这段代码
*/
if(! tree_ar[this.value].type) // 如该节点为首次进入,则记录所在层次信息
    genTreeInfo(this);
var n = 1*this.value+1;
for(i=n;i<tree_ar.length-1;i++) { // 关闭排列在当前节点之后的树
    if(tree_ar[i].type == "pad") {
        tree_ar[i].obj2.style.display = 'none';
        tree_ar[i].obj1.cells[0].innerHTML = closefolder;
    }
}
while(tree_ar[--n][0] > 1); // 回溯到当前树的起点
while(--n >= 0) // 关闭排列在当前树的起点之前的树
if(tree_ar[n].type == "pad") {
    tree_ar[n].obj2.style.display = 'none';
    tree_ar[n].obj1.cells[0].innerHTML = closefolder;
}

/** 记录层次信息,用以简化遍历树时的复杂的节点描述 **/
function genTreeInfo(o) 
{
  var el = o.parentElement;
  for(var i=0;i<el.rows.length;i++) 
  {
    if(el.rows[i].id != "") 
    {
      tree_ar[el.rows[i].value].type = el.rows[i].id;
    }
    if(el.rows[i].id == "pad" ||el.rows[i].id == "firstfolder" ||el.rows[i].id == "endfolder") 
    {
      tree_ar[el.rows[i].value].obj1 = el.rows[i];
      tree_ar[el.rows[i].value].obj2 = el.rows[i+1];
    }
  }
}

</script>

<script for=endfolder event=onclick>
// 分枝节点的点击响应,没有同级分支

v = this.parentElement.rows[this.rowIndex+1].style;
if(v.display == 'block') {
    v.display = 'none';
    this.cells[0].innerHTML = closefolder_end;
    view.innerHTML = ""; // 自行修改为参数数组定义的闭合动作
}
else 
{
    v.display = 'block';
    this.cells[0].innerHTML = openfolder_end;
    view.innerHTML = "<b>"+tree_ar[this.value][1]+"</b>"; // 自行修改为参数数组定义的展开动作
}

/**
* 以下代码用于关闭已展开的其他分枝
* 如需自行关闭展开的分枝则从这里直接返回或删去这段代码
*/
if(! tree_ar[this.value].type) // 如该节点为首次进入,则记录所在层次信息
    genTreeInfo(this);
var n = 1*this.value+1;
for(i=n;i<tree_ar.length-1;i++) { // 关闭排列在当前节点之后的树
    if(tree_ar[i].type == "pad") 
    {
        tree_ar[i].obj2.style.display = 'none';
        tree_ar[i].obj1.cells[0].innerHTML = closefolder;
    }
      
}
while(tree_ar[--n][0] > 1); // 回溯到当前树的起点
while(--n >= 0) // 关闭排列在当前树的起点之前的树
{
  if(tree_ar[n].type == "pad") 
  {
     tree_ar[n].obj2.style.display = 'none';
      tree_ar[n].obj1.cells[0].innerHTML = closefolder;
  }
 
}

/** 记录层次信息,用以简化遍历树时的复杂的节点描述 **/
function genTreeInfo(o) 
{
  var el = o.parentElement;
  for(var i=0;i<el.rows.length;i++) 
  {
    if(el.rows[i].id != "") 
    {
      tree_ar[el.rows[i].value].type = el.rows[i].id;
    }
    if(el.rows[i].id == "pad" ||el.rows[i].id == "firstfolder" ||el.rows[i].id == "endfolder") 
    {
      tree_ar[el.rows[i].value].obj1 = el.rows[i];
      tree_ar[el.rows[i].value].obj2 = el.rows[i+1];
    }
  }
}
</script>

<script for=pad event=onclick>

// 分枝节点的点击响应
v = this.parentElement.rows[this.rowIndex+1].style;
if(v.display == 'block') {
    v.display = 'none';
    this.cells[0].innerHTML = closefolder;
    view.innerHTML = ""; // 自行修改为参数数组定义的闭合动作
}else {
    v.display = 'block';
    this.cells[0].innerHTML = openfolder;
    view.innerHTML = "<b>"+tree_ar[this.value][1]+"</b>"; // 自行修改为参数数组定义的展开动作
}

/**
* 以下代码用于关闭已展开的其他分枝
* 如需自行关闭展开的分枝则从这里直接返回或删去这段代码
*/
if(! tree_ar[this.value].type) // 如该节点为首次进入,则记录所在层次信息
    genTreeInfo(this);
var n = 1*this.value+1;
for(i=n;i<tree_ar.length-1;i++) { // 关闭排列在当前节点之后的树
    if(tree_ar[i].type == "pad") {
        tree_ar[i].obj2.style.display = 'none';
        tree_ar[i].obj1.cells[0].innerHTML = closefolder;
    }
}
while(tree_ar[--n][0] > 1); // 回溯到当前树的起点
while(--n >= 0) // 关闭排列在当前树的起点之前的树
{
   if(tree_ar[n].type == "pad")
     {
       tree_ar[n].obj2.style.display = 'none';
       tree_ar[n].obj1.cells[0].innerHTML = closefolder;
     }
   if(tree_ar[n].type == "firstfolder")
     {
       tree_ar[n].obj2.style.display = 'none';
       tree_ar[n].obj1.cells[0].innerHTML = closefolder_fst;
     }
   if(tree_ar[n].type == "endfolder") 
  {
     tree_ar[n].obj2.style.display = 'none';
     tree_ar[n].obj1.cells[0].innerHTML = closefolder_end;
  }
}

/** 记录层次信息,用以简化遍历树时的复杂的节点描述 **/
function genTreeInfo(o) 
{
  var el = o.parentElement;
  for(var i=0;i<el.rows.length;i++) 
  {
    if(el.rows[i].id != "") 
    {
      tree_ar[el.rows[i].value].type = el.rows[i].id;
    }
    if(el.rows[i].id == "pad" ||el.rows[i].id == "firstfolder" ||el.rows[i].id == "endfolder") 
    {
      tree_ar[el.rows[i].value].obj1 = el.rows[i];
      tree_ar[el.rows[i].value].obj2 = el.rows[i+1];
    }
  }
}
</script>

<script for=bar event=onclick>
// 叶子节点的点击响应
view.innerHTML = "<b>"+tree_ar[this.value][1]+"</b>"; // 自行修改为参数数组定义的点击动作
</script>

<script>
/**
* 基本参数数组,根据具体应用自行扩展
* 数据可较简单的由服务器端提供
* 列1:节点层次
* 列2:节点标题
* 其余自行扩充
*/
tree_ar = new Array(
  new Array(1,"节点1"),
  new Array(2,"<a href='#'>节点2</a>"),
  new Array(2,"节点3"),
  new Array(2,"节点4"),
  new Array(3,"节点5"),
  new Array(4,"节点6"),
  new Array(5,"节点7"),
  new Array(6,"节点8"),
  new Array(7,"节点9"),
  new Array(2,"节点10"),
  new Array(1,"节点11"),
  new Array(2,"节点12"),
  new Array(2,"节点13"),
  new Array(1,"节点14"),
  new Array(1,"") // 为简化终止判断附加的空数据项
);

/*** 创建菜单 ***/
menus.innerHTML =tree(0);
</script>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -