工的上一级是部门。那么第二个元素是什么?让我们来看一下下面的一段<SELECT>定义:
<SELECT NAME="s1" onChange=" SetSubMenu(this)">
<OPTION Value="1">单位1</OPTION>
<OPTION Value="2">单位2</OPTION>
….
</SELECT>
<OPTION>元素的Value属性从哪里来呢?对,就是第二个元素,依此类推,第三个元素指的就是显示在菜单中的数据喽,即上面的"单位1"、"单位2"…
读者到这里可能有些糊涂了,说这么多,这个数组到底是什么样?别急,让我们以部门为例,给出一段根据部门库中的数据动态生成的数组模拟代码:
<SCRIPT LANGUAGE="JAVASCRIPT">
<!-
…
var arrDept = new Array();
arrDept[0] = new Array('u01', 'd01', '部门1');
arrDept[1] = new Array('u01', 'd02', '部门2');
…
arrDept[8] = new Array('u06', 'd08', '部门8');
…
arrDept[15] = new Array('u08', 'd15', '部门15');
…
->
</SCRIPT>
数组终于真相大白。以"u"开头数据的代表单位的编号,即,指向单位的指针,也就是说,我们可以通过这个编号来确定该单位所属的部门;以"d"开头的数据代表部门的编号,用来供下一级选单(即员工选单)的指针使用。(注:实际使用中,数据格式根据情况而定)
有一个问题,象单位这样没有父结点的数组该如何定义?很简单,把数组的第一个元素全部置为0就行了。
下一步,是到我们编写JavaScript代码来控制菜单的显示的时候了。我们就假定您生成的三个数组分别命名为arrUnit,arrDept,arrEmp。
四、编写JavaScript代码,控制菜单的显示
其实有经验的程序员,读到这里应该知道如何进行下去。但您不妨读下去,也许,笔者的方法对您未必不是一种新的尝试。而且,据我猜测,读我这篇文章的大多数都是没有经验的程序员,呵呵,帮人帮到底吧。Come On, Let's Go.
让菜单显示出来,其实有好几种思路。利用ASP等程序直接生成<SELECT>结构、利用OPTION对象的ADD和Remove方法动态添加和改变等等,都是可以使用的方法。但,经过笔者的多次实践和摸索,有一种方法更为有效,那就是利用Script代码动态的改写整个<SELECT>框架。
好,就让我们从加载页面(document)开始,一步一步的讲解JavaScript代码到底是如何控制菜单的显示的。
既然有三个菜单,那么我们就得事先设计出这样的HTML代码(其实要不要无所谓,放在那里只是为了便于理解):
<BODY BGCOLOR="#FFFFFF" ONLOAD="body_onload()">
...
<TD>
<SELECT NAME="s0" ONCHANGE="SetSubmenu(this)"></SELECT>
</TD>
<TD>
<SELECT NAME="s1" ONCHANGE="SetSubmenu(this)"></SELECT>
</TD>
<TD>
<SELECT NAME="s2" ONCHANGE="SetSubmenu(this)"></SELECT>
</TD>
</BODY>
您有可能要问,这里怎么什么数据都没有?不要奇怪,等一下您自然就会明白。我们来看一下<BODY>对象的ONLOAD事件body_onload()做了些什么工作?
function body_onload(){
var TD = GetParent(document.all("s0"), "TD");
TD.innerHTML = MakeMenu(arrUnit, 0, 0, "s0", 1);
TD = GetParent(document.all("s1"), "TD");
TD.innerHTML = MakeMenu(arrDept, GetSelectValue(document.all("s0")), 0, "s1", 1);
TD = GetParent(document.all("s2"), "TD");
TD.innerHTML = MakeMenu(arrEmp, GetSelectValue(document.all("s1")), 0, "s2", 1);
}
让我们来研究一下。首先程序利用GetParent()函数取得s0的容器TD对象句柄,然后,利用MakMenu()函数产生菜单代码,并把代码赋值给刚才取得的TD对象;然后是s1,接着是s2.。GetParent()函数定义如下:
function GetParent(src, tag){
if (src && src.tagName!=tag){
return(GetParent(src.parentElement, tag));
}
return src;
}
这里的tag参数必须大写,例如TD、TR、TABLE,函数返回的是离src指定的元素最近的由tag标签定义的父对象。
我们要特别说明一下MakeMenu()函数,这个函数的作用不言而喻--产生菜单的HTML定义,先看看函数定义:
function MakeMenu(arrSub, pValue, cValue, name, bulSkip){
var sHTML = "<select name='" + name + "' " + tag + arrSub[i][2] + "</option>";
}
}
sHTML += "</select>";
return sHTML;
}
来看一下参数的含义。arrSub,指的是菜单数据的来源,其实就是我们上文定义的数组;pValue,指定父结点的编号,根据这个编号,我们可以找出所有的子结点数据;cValue,指定菜单的默认显示项;name,指定产生的<SELECT>菜单的名称;bulSkip,指定菜单的默认显示项是"<未选择>"还是具体数据。
GetSelectValue()函数的目的,就是取得<SELECT>对象当前显示的值。如果没有显示任何值,函数返回0。
function GetSelectValue(oSelect){
if (oSelect.selectedIndex < 0) return 0;
return oSelect.options(oSelect.selectedIndex).value;
}
那么,当用户加载页面之后,首先运行的就是body_onload()函数,该函数根据已经产生的JavaScript多维数组,利用MakeMenu()函数动态的生成菜单的HTML代码,并根据DHTML的原理加载到页面中。OK,运行一下页面,看看菜单是否正常显示?如果有什么问题,抓紧时间好好调试一下,例如数据库的连接是否正常,javascript代码的大小写是否正确,数组的定义是否有什么问题…
下一步,选择菜单…等一下,好像还有什么遗漏,对了,我们还必须为<SELECT>对象的onchange事件添加程序代码:
function SetSubMenu(pSelect){
var oOption, sValue;
if (pSelect.selectedIndex < 0) return;
switch (pSelect.name){
case "s0":
var TD = GetParent(document.all("s1"), "TD");
TD.innerHTML = MakeMenu(arrDept, GetSelectValue("s0"), "0", "s1", 0);
TD = GetParent(document.all("s2"), "TD");
TD.innerHTML = MakeMenu(arrEmp, GetSelectValue("s1"), "0", "s2", 0);
break;
case "s1":
var TD = GetParent(document.all("s2"), "TD");
TD.innerHTML = MakeMenu(arrEmp, GetSelectValue("s1"), "0", "s2", 0);
break;
default:
}
}
好了,我们再检查一下,还有没有什么遗漏。从第一个下拉菜单中选择单位,立即,第二个下拉菜单和第三个下拉菜单都发生了变化,看看是不是想要的。(不是?呵呵,回头好好检查);再在第二个下拉菜单中选择部门,看看员工的下拉菜单是否跟着改变?
恭喜你,你已经成功的实现了三维下拉菜单。其实,对于二维菜单,实现的方法完全一致。读者完全可以利用本文的方法实现WEB项目菜单的全攻略。以后再遇到类似的问题,我想这回你一定可以毫不犹豫的说,让我来搞定它。
上一页 [1] [2]