日期:2014-05-16 浏览次数:20482 次
网页里的树形菜单有两种实现方式:一种是结合后台(JSP/Struts2等), 每次下载不同的数据来刷新页面,实现树形菜单的效果。另一种是由纯JavaScript方式来实现,在树形菜单的工作过程中,不会反复从后台重新下载页面。本文要介绍的就是用纯JavaScript来实现一个树形菜单。
1. 原理
基本原理是利用HTML Tag的innerHTML属性来实现动态效果,像<div> <span> <p>等标签都可以作为一个容器,通过控制其innerHTML来刷新显示内容。显然,其内容是由JavaScript来动态生成的。
做一个例子演示一下:
<span id="sample"></span>
<script>
var sampleExpanded = true;
function sampleOnClick()
{
sampleExpanded = ! sampleExpanded;
sampleRefreshUI();
}
function sampleRefreshUI()
{
var html = "<a href='javascript:sampleOnClick()' > ";
if(sampleExpanded)
{
html += "-";
html += " 菜单项<br/>";
html += "</a>";
html += " ---子菜单1---<br/>";
html += " ---子菜单2---<br/>";
html += " ---子菜单3---<br/>";
}
else
{
html += "+";
html += " 菜单项<br/>";
html += "</a>";
}
document.getElementById("sample").innerHTML = html;
}
sampleRefreshUI();
</script>(1) 要放一个内容为空的<span>作为目标容器,我们用JavaScript动态修改其中的HTML内容
(2) 定义一个变量sampleExpanded 来存储状态: true, 当前为展开, false当前为折叠
(3) 在容器里放上链接 <a href="javascript:sampleOnClick( )"> *** </a>,当该链接被点击时sampleOnClick( )函数被调用。
(4) sampleOnClick( ) 改变变量的值(反转),然后调用sampleRefreshUI( )更换目标窗口的内容显示:当sampleExpanded为true时,显示内容为“-”及子菜单项;当为false时,显示内容为"+"。即一个简单的展开、折叠效果。

2. 构建菜单树
真正的菜单有多个菜单项,每一组都可以独立的展开、折叠,因此,仅一个变量sampleExpanded是不足以保存这么多数据的。应该一个数组,来保存每组菜单的文本和状态信息。再统一的生成一个树状展示。
定义菜单为Menu, 菜单项为MenuItem
function MenuItem(l, h, t)
{
this.label = l;
this.href = h;
this.target = t;
}
function Menu(lb)
{
this.itemArray = new Array();
this.expanded = true;
this.index = -1;
this.label = lb;
this.addItem = function(l, h, t)
{
var item = new MenuItem(l,h,t);
this.itemArray.push(item);
};
}再定义一个MenuTree,来统一的管理各Menu,并负责生成innerHtml
function MenuTree(container)
{
this.menuArray = new Array();
this.count = 0;
this.span = container;
this.target = null;
// 图标
this.iconOpen = null;
this.iconClosed = null;
// 选中的菜单项
this.menuSelected = -1;
this.menuItemSelected = -1;
this.setDefaultTarget = function(target)
{
};
this.setIcon = function(urlOpen, urlClosed)
{
};
this.addMenu = function(menu)
{
};
this.getMenu = function(index)
{
};
this.expandAll = function(yes)
{
};
this.toHtml = function()
{
};
}
我把函数实现都给去了,相信大家可以根据这个框架来实现一个全功能的菜单了。注意回调函数sampleOnClick()和界面刷新函数sampleRefreshUI()仍然是必要的,只是sampleOnClick()应该传入一个参数,表示是哪个Menu被点击了。