无限级联动菜单
目前的制作任务中需要用到多级联动,于是想找一种通用的解决办法。花了一点时间,得到一个的解决方案。
演示:点击查看演示(链接已失效)
首先考察数据结构的设计。
通常做分类,我们需要一个类别编号和一个类别名称,因为从属关系,我们也需要一个上级类别的编号。那么我们得到的就是一个三个字段的一维表。实际应用中,可以使用数据库来实现,但是在这里我采用多维数组简单模拟该数据库(实际应用中可能也会考虑将数据库中的内容生成 JavaScript 代码)。代码如下:
JavaScript代码
var arrSorts = new Array(35);
arrSorts[0] = ["1", "主类别一", "0"];
arrSorts[1] = ["2", "主类别二", "0"];
arrSorts[2] = ["3", "主类别三", "0"];
arrSorts[3] = ["4", "小类一", "1"];
arrSorts[4] = ["5", "小类二", "1"];
...
arrSorts[33] = ["34", "终极类十一", "24"];
arrSorts[34] = ["35", "终极类十二", "24"];
arrSorts[35] = ["36", "终极类十三", "24"];
首先是一个一维数组,构成了数据库的行,它的每一个项又是一个包含三个项的一维数组,每个相对应数据库的一列,分别是“类别编号”、“类别名称”和“所属类别”。
然后是具体的程序的设计
我们在页面中增加两个元素,分别用来显示菜单和选中的值。代码如下:
<p id="abc"></p>
<input type="text" id="defg" value="" />
JavaScript 部分代码,首先要初始化,列出第一级类别,子程序如下:
function initSorts(os1, os2) { //初始化选项,主类别
var s = "";
s = s + "<select onchange="setSorts(this, + os1 + , + os2 + );">";
s = s + "<option value="">----</option>";
for (var i = 0; i < arrSorts.length; i++) {
if (arrSorts[i][2] == 0) {
s = s + "<option value="" + arrSorts[i][0] + "">" + arrSorts[i][1] + "";
}
}
s = s + "</select>";
document.getElementById(os2).innerHTML = s;
}
这个部分的思路比较简单。我们将第一级分类的上级分类编号定为 0 ,主要循环判断,找出第三个字段时 0 的项,生成对应的代码即可。
生成下级菜单部分,均通过 onchange 行为调用一个子程序 setSort(),代码如下:
function setSorts(o, os1, os2) {
//清除下级选项
while (o.nextSibling) {
o.parentNode.removeChild(o.nextSibling);
}
//获取当前选项 ID ,并设置选择值
var iValue = o.options[o.selectedIndex].value;
if (iValue == "") return false;
document.getElementById(os1).value = iValue;
//将选中的选项对应代码更改为 selected
var s = document.getElementById(os2).innerHTML;
s = s .replace("<option value="" + iValue + "">", "<option value="" + iValue + "" selected>");
//新的下拉列表代码
var s1 = "";
for (var i = 0; i < arrSorts.length; i++) {
if (arrSorts[i][2] == iValue) {
if (s1 == "") {
s1 = s1 + "<select onchange="setSorts(this, + os1 + , + os2 + );">";
s1 = s1 + "<option value="">----</option>";
s1 = s1 + "<option value="" + arrSorts[i][0] + "">" + arrSorts[i][1] + "</option>";
}
else {
s1 = s1 + "<option value="" + arrSorts[i][0] + "">" + arrSorts[i][1] + "</option>";
}
}
}
if (s1 != "") s1 = s1 + "</select>";
//显示代码
document.getElementById(os2).innerHTML = s + s1;
}
这里需要注意几个地方:
每选择一个项,都要清除掉后续的级别。这个功能在中间更改选项的时候尤其重要,否则新的菜单均加在最后,菜单会越来越多。
替换被选中的项的代码。因为通过 Element.innerHTML 获得的代码中没有更改被选择的项的状态,所以我们手工更改为 selected 状态。
代码都比较简单,但是基本上实现了功能。其中用到了一些 DOM 知识,临时查阅解决的。^_^
程序上难免有不完善的地方,以后会逐步改进。