首页logo
  •  

jonllen

金龙,目前就职于一家软件公司,从事Java和.Net信息安全开发设计。

个人档案

jonllen
心情闪存 | 给他留言
妮称:jonllen
来自:中国. 湖南. 湘潭
简述:金龙,目前就职于一家软件公司,从事Java和.Net信息安全开发设计。
博客日历

JavaScript无限级Select下拉列表联动

分类:JavaScript

实现效果: - -

代码如下:

地区:<select id="drpProvince"></select> - <select id="drpCity"></select> - <select id="drpArea"></select>
<script type="text/javascript">
//联动select数组
var arrSelect = new Array(document.getElementById("drpProvince"), document.getElementById("drpCity"), document.getElementById("drpArea"));
//多围数组数据,四围分别保存id、父级id、显示文本、文本值
var arrData = new Array(
<!--[999999,0,'--请选择--',''],[999998,999999,'--请选择--',''],[999997,999998,'--请选择--',''],-->
[
1,0,'北京','1'],[2,1,'北京','2']
,[
3,0,'湖南','3'],[4,3,'长沙','4'],[5,3,'株洲','5'],[6,3,'湘潭','6'],[7,6,'岳塘区','7'],[8,6,'雨湖区','8'],[9,6,'河塘区','9']
,[
10,0,'广东','10'],[11,10,'广州','11'],[12,10,'佛山','12'],[13,11,'天河区','13'],[14,11,'番禺区','14'],[15,11,'越秀区','15'],[16,12,'南山区','16'],[17,12,'蝉城区','17']
);
//默认值数组
var arrDefault = new Array('10' ,'11' ,'13');
//初始化主函数
function arrInit(strInitID, arrSelect, arrMatrix, arrDefValue) {
function doChange(iIndex) {
var iCount = 0;
var sParentID = strInitID;
if (iIndex > 0) sParentID = arrSelect[iIndex - 1].options[arrSelect[iIndex - 1].selectedIndex].ID;
with (arrSelect[iIndex]) {
length
= 0;
options[iCount
++] = new Option('--所有--', '0', false, true);
for (var i = 0; i < arrMatrix.length; i++) {
if (String(arrMatrix[i][1]) == String(sParentID)) {
var oNewOption = new Option(arrMatrix[i][2], arrMatrix[i][3], false, false);
oNewOption.ID
= arrMatrix[i][0];
options[iCount
++] = oNewOption;
if(arrMatrix[i][3] == arrDefValue[iIndex])options[iCount - 1].selected = true;
};
};
/* if (iCount == 0) { //列表数为0则新增默认项
var oNull = new Option("--", null, false, true);
oNull.ID = "_0x" + (new Date()).getTime();
options[0] = oNull;
};
*/

//联动改变所有子select
if (++iIndex < arrSelect.length) doChange(iIndex);
};
};
if (!arrDefValue) arrDefValue = [];
for (var i = 0; i < arrSelect.length - 1; i++) {
eval(
"arrSelect[" + i + "].onchange = function(){ doChange(" + (i + 1) + "); };");
}
doChange(
0);
//只有第一次调用初始化主函数arrInit才使用默认值,之后手动选择不受默认值限制,因此清空。
arrDefValue = [];
};
arrInit(
0,arrSelect,arrData,arrDefault);
</script>

这是我以前在网上看到一个NB人物写的代码,感觉用起来很方便,于是便记录了下来,自己在它之上进行了一些修改,使在添加子项的时候不管有没有子项都添加一个为--所有--的默认项,这样做的用意就不用多说了吧,就像上面省市区3级联动的例子来说,我要表示一个市的地区,但不一定会要是精确到市下面的某一个区,这时候在所有的市下面加个所有就很要必要了。以上select联动实现有如下功能:

1.支持无限级的select层次嵌套。

首先,使用数组方式存储数据结构使它之能支持无限级。其实话说无限级的话只不过是说不受限制,这些数据都是后台程序动态输出,比如从数据库内取出来,一般使用id,父id这种表结构就能很好的存储无限级层次结构,所以在js里面使用这种结构的数组也能存储无限级别,即[id,父id,显示文本,文本值],这样程序处理的时候直接用一条sql语句取出所有的数据一次性输出,这样每选择一个项也就不必要使用Ajax去服务器端取下一级的子项了,全部放在客户端处理。

2.支持初始化默认选择值设定。

这一点很重要,程序里面编辑的功能就一定会用到,就是在初始化的时候除开加载所有数据,一定还要能根据指定值设置默认选择项,上面就是为arrDefault数组,它分别对应arrSelect数组的默认选择项,应该和arrSelect围数相同,由于初始化列表项和指定默认值是在doChange函数里执行的,而且select的onchange事件也是调用doChange函数,所以在调用doChange(0)从第0个select初始化后重值默认值为[],为了使后面的手动选择的一定不会是选中默认值项,所以设置为[]长度为0的数组,使用索引取得的值都是undefined,所以等式arrMatrix[i][3] == arrDefValue[iIndex]就不会成立。

3.代码简洁。

使用闭包申明内部函数调用外部的变量,用eval来动态绑定select的onchange事件,使之把所有的逻辑处理都交给doChange函数,而不是初始化、设定默认值、change事件分别一个函数。doChange函数接受一个参数为arrSelect数组的索引号,即是从那一个select开始改变,在arrInit初始化函数当然是从第0个开始,触发onchange事件的时候是从当前select的下一个开始改变,使用++iIndex < arrSelect.length将循环到最后一个select改变。sParentID父id默认为strInitID即是0(所有1级的select父id全为0),当iIndex>0即是2级或以下select时sParentID父id就不可能再是0了,而是arrSelect[iIndex - 1].options[arrSelect[iIndex - 1].selectedIndex].ID上一级select选择项的id(初始化时已指定),根据父id循环arrMatrix数据数组找出父id为此值的所有列表,再依次循环到子级select。

语法点:

1.with使用。with使用{}包括的作用域设置为后面()包括的对象,所以{}里使用的属性或方法就会去()包括的对象上下文里找,而不需要使用对象.去访问,上面代码里的length = 0实际就等于arrSelect[iIndex].length = 0,但是w3c提示我们:with 语句是运行缓慢的代码块,尤其是在已设置了属性值时。大多数情况下,如果可能,最好避免使用它。

2.Option使用。指定select.options数组直接赋值,w3c说明里面讲到options[]集合并非一个普通的 HTMLcollection。为了和早期的浏览器向后兼容,这个集合有某种特殊的行为:允许通过 Select 对象来改变显示的选项,所以直接使用索引指定一个Option能起到动态添加或设置select列表项功能。为什么不使用select.add呢?因为在ie里面add方法只接受一个参数就是新增加的Option,而w3c标准是有2个参数,参数2为before必需,在选项数组的该元素之前增加新的元素。如果该参数是null,元素添加到选项数组的末尾。虽然使用try、catch能做到兼容,但为了取同不多做无味判断舍弃add方法。而new Option(text, value, defaultSelected, selected)四个参数的构造函数是从Navigator 3.0起添加的,defaultSelected是指定是否默认选择,selected则指定当前Option是否能被选择。


标签:JavaScript
  • posted@ 2009-06-28 14:46
  • update@ 2009-11-04 01:56:45
  • 阅读(13437)
  • 评论(3)

相关文章

评论
1楼 applezqp 2009-11-04 11:51:46
代码给个易读的版本,我再来拜读一下。
回复:呃…… 看来我写的东西易读性很差~~(2009-11-05 10:06:10)
2楼 applezqp 2009-11-04 11:52:51
评论被隐藏了。呃……上次我发的一条评论直接就没了,什么原因呢?
回复:现在我设置提交的评论前台默认不显示,至于不见没有吧?(2009-11-05 10:11:41)
3楼 布布在线 2011-04-12 14:58:48
如果是所有地区铺开,然后鼠标移到显示省下2级地区浮动块,让选择,这个效果很好的。3个下拉框太单调。。
发表评论
*必填
回复通知我
*必填