?


















































--------------------------------------------------------------
能夠根據自定義的菜單數據和select,自動設置聯級的下拉菜單,可定義默認值。
效果:
其中參數1是菜單結構:


var?menu?=?[
????{'val':?'1',?'txt':?'value'},
????{'val':?'2?->',?'menu':?[
????????{'val':?'2_1'},
????????{'val':?'2_2'}
????]},
????{'val':?'3?->',?'menu':?[
????????{'val':?'3_1?->',?'menu':?[
????????????{'val':?'3_1_1'},
????????????{'val':?'3_1_2'}
????????]},
????????{'val':?'3_2'}
????]},
????{'val':?'4?->',?'menu':?[
????????{'val':?'4_1?->',?'menu':?[
????????????{'val':?'4_1_1?->',?'menu':?[
????????????????{'val':?'4_1_1_1'}
????????????]}
????????]}
????]}
];
參數2是select的id集合(按順序):
var?sel=["sel1","sel2","sel3","sel4","sel5"]
可設置默認值(按順序):
var?val=["3?->",?"3_1?->",?"3_1_2"];
源碼:
<!DOCTYPE?html?PUBLIC?"-//W3C//DTD?XHTML?1.0?Transitional//EN"?"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html?xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta?http-equiv="Content-Type"?content="text/html;?charset=gb2312"?/>
<title>JavaScript?自定義多級聯動下拉菜單</title>
<script?type="text/javascript">
var?$?=?function?(id)?{
????return?"string"?==?typeof?id???document.getElementById(id)?:?id;
};
function?addEventHandler(oTarget,?sEventType,?fnHandler)?{
????if?(oTarget.addEventListener)?{
????????oTarget.addEventListener(sEventType,?fnHandler,?false);
????}?else?if?(oTarget.attachEvent)?{
????????oTarget.attachEvent("on"?+?sEventType,?fnHandler);
????}?else?{
????????oTarget["on"?+?sEventType]?=?fnHandler;
????}
};
function?Each(arrList,?fun){
????for?(var?i?=?0,?len?=?arrList.length;?i?<?len;?i++)?{?fun(arrList[i],?i);?}
};
function?GetOption(val,?txt)?{
????var?op?=?document.createElement("OPTION");
????op.value?=?val;?op.innerHTML?=?txt;
????return?op;
};
var?Class?=?{
??create:?function()?{
????return?function()?{
??????this.initialize.apply(this,?arguments);
????}
??}
}
Object.extend?=?function(destination,?source)?{
????for?(var?property?in?source)?{
????????destination[property]?=?source[property];
????}
????return?destination;
}
var?CascadeSelect?=?Class.create();
CascadeSelect.prototype?=?{
??//select集合,菜單對象
??initialize:?function(arrSelects,?arrMenu,?options)?{
????if(arrSelects.length?<=?0?||?arrMenu.lenght?<=?0)?return;//菜單對象
????
????var?oThis?=?this;
????
????this.Selects?=?[];//select集合
????this.Menu?=?arrMenu;//菜單對象
????
????this.SetOptions(options);
????
????this.Default?=?this.options.Default?||?[];
????
????this.ShowEmpty?=?!!this.options.ShowEmpty;
????this.EmptyText?=?this.options.EmptyText.toString();
????
????//設置Selects集合和change事件
????Each(arrSelects,?function(o,?i){
????????addEventHandler((oThis.Selects[i]?=?$(o)),?"change",?function(){?oThis.Set(i);?});
????});
????
????this.ReSet();
??},
??//設置默認屬性
??SetOptions:?function(options)?{
????this.options?=?{//默認值
????????Default:????[],//默認值(按順序)
????????ShowEmpty:????false,//是否顯示空值(位于第一個)
????????EmptyText:????"請選擇"//空值顯示文本(ShowEmpty為true時有效)
????};
????Object.extend(this.options,?options?||?{});
??},
??//初始化select
??ReSet:?function()?{
??
????this.SetSelect(this.Selects[0],?this.Menu,?this.Default.shift());
????this.Set(0);
??},
??//全部select設置
??Set:?function(index)?{
????var?menu?=?this.Menu
????
????//第一個select不需要處理所以從1開始
????for(var?i=1,?len?=?this.Selects.length;?i?<?len;?i++){
????????if(menu.length?>?0){
????????????//獲取菜單
????????????var?value?=?this.Selects[i-1].value;
????????????if(value!=""){
????????????????Each(menu,?function(o){?if(o.val?==?value){?menu?=?o.menu?||?[];?}?});
????????????}?else?{?menu?=?[];?}
????????????
????????????//設置菜單
????????????if(i?>?index){?this.SetSelect(this.Selects[i],?menu,?this.Default.shift());?}
????????}?else?{
????????????//沒有數據
????????????this.SetSelect(this.Selects[i],?[],?"");
????????}
????}
????//清空默認值
????this.Default.length?=?0;
??},
??//select設置
??SetSelect:?function(oSel,?menu,?value)?{
????oSel.options.length?=?0;?oSel.disabled?=?false;
????if(this.ShowEmpty){?oSel.appendChild(GetOption("",?this.EmptyText));?}
????if(menu.length?<=?0){?oSel.disabled?=?true;?return;?}
????
????Each(menu,?function(o){
????????var?op?=?GetOption(o.val,?o.txt???o.txt?:?o.val);?op.selected?=?(value?==?op.value);
????????oSel.appendChild(op);
????});????
??},
??//添加菜單
??Add:?function(menu)?{
????this.Menu[this.Menu.length]?=?menu;
????this.ReSet();
??},
??//刪除菜單
??Delete:?function(index)?{
????if(index?<?0?||?index?>=?this.Menu.length)?return;
????for(var?i?=?index,?len?=?this.Menu.length?-?1;?i?<?len;?i++){?this.Menu[i]?=?this.Menu[i?+?1];?}
????this.Menu.pop()
????this.ReSet();
??}
};
window.onload=function(){
????
????var?menu?=?[
????????{'val':?'1',?'txt':?'value'},
????????{'val':?'2?->',?'menu':?[
????????????{'val':?'2_1'},
????????????{'val':?'2_2'}
????????]},
????????{'val':?'3?->',?'menu':?[
????????????{'val':?'3_1?->',?'menu':?[
????????????????{'val':?'3_1_1'},
????????????????{'val':?'3_1_2'}
????????????]},
????????????{'val':?'3_2'}
????????]},
????????{'val':?'4?->',?'menu':?[
????????????{'val':?'4_1?->',?'menu':?[
????????????????{'val':?'4_1_1?->',?'menu':?[
????????????????????{'val':?'4_1_1_1'}
????????????????]}
????????????]}
????????]}
????];
????
????var?sel=["sel1",?"sel2",?"sel3",?"sel4",?"sel5"];
????
????var?val=["3?->",?"3_1?->",?"3_1_2"];
????
????var?cs?=?new?CascadeSelect(sel,?menu,?{?Default:?val?});
????
????$("btnA").onclick=function(){cs.ShowEmpty=!cs.ShowEmpty;}
????
????$("btnB").onclick=function(){
????????cs.Add(
????????????{'val':?'5?->',?'menu':?[
????????????????{'val':?'5_1?->',?'menu':?[
????????????????????{'val':?'5_1_1?->',?'menu':?[
????????????????????????{'val':?'5_1_1_1?->',?'menu':?[
????????????????????????????{'val':?'5_1_1_1_1'}
????????????????????????]}
????????????????????]}
????????????????]}
????????????]}
????????)
????}
????
????$("btnC").onclick=function(){
????????cs.Delete(3)
????}
}
</script>
<style?type="text/css">
.sel?select{?width:100px;}
</style>
</head>
<body>
<div?class="sel">
<select?id="sel1"></select>
<select?id="sel2"></select>
<select?id="sel3"></select>
<select?id="sel4"></select>
<select?id="sel5"></select>
</div>
<br?/>
<div>
<input?id="btnA"?type="button"?value="顯示/不顯示空值"?/>
<input?id="btnB"?type="button"?value="添加菜單"?/>
<input?id="btnC"?type="button"?value="減少菜單"?/>
</div>
</body>
</html>
<html?xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta?http-equiv="Content-Type"?content="text/html;?charset=gb2312"?/>
<title>JavaScript?自定義多級聯動下拉菜單</title>
<script?type="text/javascript">
var?$?=?function?(id)?{
????return?"string"?==?typeof?id???document.getElementById(id)?:?id;
};
function?addEventHandler(oTarget,?sEventType,?fnHandler)?{
????if?(oTarget.addEventListener)?{
????????oTarget.addEventListener(sEventType,?fnHandler,?false);
????}?else?if?(oTarget.attachEvent)?{
????????oTarget.attachEvent("on"?+?sEventType,?fnHandler);
????}?else?{
????????oTarget["on"?+?sEventType]?=?fnHandler;
????}
};
function?Each(arrList,?fun){
????for?(var?i?=?0,?len?=?arrList.length;?i?<?len;?i++)?{?fun(arrList[i],?i);?}
};
function?GetOption(val,?txt)?{
????var?op?=?document.createElement("OPTION");
????op.value?=?val;?op.innerHTML?=?txt;
????return?op;
};
var?Class?=?{
??create:?function()?{
????return?function()?{
??????this.initialize.apply(this,?arguments);
????}
??}
}
Object.extend?=?function(destination,?source)?{
????for?(var?property?in?source)?{
????????destination[property]?=?source[property];
????}
????return?destination;
}
var?CascadeSelect?=?Class.create();
CascadeSelect.prototype?=?{
??//select集合,菜單對象
??initialize:?function(arrSelects,?arrMenu,?options)?{
????if(arrSelects.length?<=?0?||?arrMenu.lenght?<=?0)?return;//菜單對象
????
????var?oThis?=?this;
????
????this.Selects?=?[];//select集合
????this.Menu?=?arrMenu;//菜單對象
????
????this.SetOptions(options);
????
????this.Default?=?this.options.Default?||?[];
????
????this.ShowEmpty?=?!!this.options.ShowEmpty;
????this.EmptyText?=?this.options.EmptyText.toString();
????
????//設置Selects集合和change事件
????Each(arrSelects,?function(o,?i){
????????addEventHandler((oThis.Selects[i]?=?$(o)),?"change",?function(){?oThis.Set(i);?});
????});
????
????this.ReSet();
??},
??//設置默認屬性
??SetOptions:?function(options)?{
????this.options?=?{//默認值
????????Default:????[],//默認值(按順序)
????????ShowEmpty:????false,//是否顯示空值(位于第一個)
????????EmptyText:????"請選擇"//空值顯示文本(ShowEmpty為true時有效)
????};
????Object.extend(this.options,?options?||?{});
??},
??//初始化select
??ReSet:?function()?{
??
????this.SetSelect(this.Selects[0],?this.Menu,?this.Default.shift());
????this.Set(0);
??},
??//全部select設置
??Set:?function(index)?{
????var?menu?=?this.Menu
????
????//第一個select不需要處理所以從1開始
????for(var?i=1,?len?=?this.Selects.length;?i?<?len;?i++){
????????if(menu.length?>?0){
????????????//獲取菜單
????????????var?value?=?this.Selects[i-1].value;
????????????if(value!=""){
????????????????Each(menu,?function(o){?if(o.val?==?value){?menu?=?o.menu?||?[];?}?});
????????????}?else?{?menu?=?[];?}
????????????
????????????//設置菜單
????????????if(i?>?index){?this.SetSelect(this.Selects[i],?menu,?this.Default.shift());?}
????????}?else?{
????????????//沒有數據
????????????this.SetSelect(this.Selects[i],?[],?"");
????????}
????}
????//清空默認值
????this.Default.length?=?0;
??},
??//select設置
??SetSelect:?function(oSel,?menu,?value)?{
????oSel.options.length?=?0;?oSel.disabled?=?false;
????if(this.ShowEmpty){?oSel.appendChild(GetOption("",?this.EmptyText));?}
????if(menu.length?<=?0){?oSel.disabled?=?true;?return;?}
????
????Each(menu,?function(o){
????????var?op?=?GetOption(o.val,?o.txt???o.txt?:?o.val);?op.selected?=?(value?==?op.value);
????????oSel.appendChild(op);
????});????
??},
??//添加菜單
??Add:?function(menu)?{
????this.Menu[this.Menu.length]?=?menu;
????this.ReSet();
??},
??//刪除菜單
??Delete:?function(index)?{
????if(index?<?0?||?index?>=?this.Menu.length)?return;
????for(var?i?=?index,?len?=?this.Menu.length?-?1;?i?<?len;?i++){?this.Menu[i]?=?this.Menu[i?+?1];?}
????this.Menu.pop()
????this.ReSet();
??}
};
window.onload=function(){
????
????var?menu?=?[
????????{'val':?'1',?'txt':?'value'},
????????{'val':?'2?->',?'menu':?[
????????????{'val':?'2_1'},
????????????{'val':?'2_2'}
????????]},
????????{'val':?'3?->',?'menu':?[
????????????{'val':?'3_1?->',?'menu':?[
????????????????{'val':?'3_1_1'},
????????????????{'val':?'3_1_2'}
????????????]},
????????????{'val':?'3_2'}
????????]},
????????{'val':?'4?->',?'menu':?[
????????????{'val':?'4_1?->',?'menu':?[
????????????????{'val':?'4_1_1?->',?'menu':?[
????????????????????{'val':?'4_1_1_1'}
????????????????]}
????????????]}
????????]}
????];
????
????var?sel=["sel1",?"sel2",?"sel3",?"sel4",?"sel5"];
????
????var?val=["3?->",?"3_1?->",?"3_1_2"];
????
????var?cs?=?new?CascadeSelect(sel,?menu,?{?Default:?val?});
????
????$("btnA").onclick=function(){cs.ShowEmpty=!cs.ShowEmpty;}
????
????$("btnB").onclick=function(){
????????cs.Add(
????????????{'val':?'5?->',?'menu':?[
????????????????{'val':?'5_1?->',?'menu':?[
????????????????????{'val':?'5_1_1?->',?'menu':?[
????????????????????????{'val':?'5_1_1_1?->',?'menu':?[
????????????????????????????{'val':?'5_1_1_1_1'}
????????????????????????]}
????????????????????]}
????????????????]}
????????????]}
????????)
????}
????
????$("btnC").onclick=function(){
????????cs.Delete(3)
????}
}
</script>
<style?type="text/css">
.sel?select{?width:100px;}
</style>
</head>
<body>
<div?class="sel">
<select?id="sel1"></select>
<select?id="sel2"></select>
<select?id="sel3"></select>
<select?id="sel4"></select>
<select?id="sel5"></select>
</div>
<br?/>
<div>
<input?id="btnA"?type="button"?value="顯示/不顯示空值"?/>
<input?id="btnB"?type="button"?value="添加菜單"?/>
<input?id="btnC"?type="button"?value="減少菜單"?/>
</div>
</body>
</html>