实现select菜单联动的javascript方案

来源:互联网 发布:橡树岭实验室 知乎 编辑:程序博客网 时间:2024/05/21 04:18

<script language=javascript src="test.js"></script>
<xml id="cascadeMenuDefinition">
<config-root>
 <select-menu name="level1">
  <item display="A" value="A"/>
  <item display="B" value="B"/>
  <item display="C" value="C"/>
 </select-menu>
 <select-menu name="level2">
  <item display="A00" value="00" parentValue="A"/>
  <item display="B01" value="01" parentValue="B"/>
  <item display="C02" value="02" parentValue="C"/>
 </select-menu>
 <select-menu name="level3">
  <item display="A0001" value="0001" parentValue="00"/>
  <item display="B0102" value="0102" parentValue="01"/>
  <item display="C0203" value="0203" parentValue="02"/>
 </select-menu>
</config-root>
</xml>


<body>
<form>
<select id="menu1" useXmlBinding=true dataSource="level1" subMenus="menu2;menu3"></select>
<select id="menu2" useXmlBinding=true dataSource="level2" selectedValue="01"></select>
<select id="menu3" useXmlBinding=true dataSource="level2" subMenus="menu4"></select>
<select id="menu4" useXmlBinding=true dataSource="level3"></select>
</form>
</body>

 

test.js:

window.attachEvent("onload",initXMLCascadeMenu);
function $(id){
 return document.getElementById(id);
}
/**
* XmlCascadeMenuHelper:用以维护一组select的dataSource定义,包括select items
*/
var XmlCascadeMenuHelper=new Object();
CascadeMenuConfig=new Array();//存储介质
/**
* initXMLCascadeMenu,页面onload时载入调用,用以管理异常和调用缓存数据、绑定数据的方法
*/
function initXMLCascadeMenu(){
 window.status="初始化XML级联菜单";
 try{
  cacheXMLCascadeMenu();
  bindXmlCascadeMenu();
 }catch(e){
  alert(e.message);
 }
 window.status=window.defaultStatus;
}
/**
* 将数据岛内的定义读入内存,数据岛的id必须为cascadeMenuDefinition
*/
function cacheXMLCascadeMenu(){
 var xmlIsland=$("cascadeMenuDefinition");
 //读入并封装到XMLDOM
 var xmldoc = new ActiveXObject("Microsoft.XMLDOM");
 xmldoc.async = false;
 xmldoc.loadXML(xmlIsland.innerHTML);
 var config=xmldoc.documentElement;
 var menus=config.childNodes;
 var menulen=menus.length;
 for(var i=0;i<menulen;i++){
  var menuNode=menus[i];
  var menuName=XmlUtil.getProperty(menuNode,"name");
  var menuObj=new CascadeMenu();
  var items=menuNode.childNodes;
  var itemlen=items.length;
  for(var j=0;j<itemlen;j++){
   var itemNode=items[j];
   var itemObj=new CascadeMenu();
   itemObj.display=XmlUtil.getProperty(itemNode,"display");
   itemObj.value=XmlUtil.getProperty(itemNode,"value");
   itemObj.parentValue=XmlUtil.getProperty(itemNode,"parentValue");
   menuObj.addItem(itemObj);
  }
  CascadeMenuConfig[menuName]=menuObj;
 }
}
/**
* 便利所有的表单select并绑定
*/
function bindXmlCascadeMenu(){
 var forms=document.forms;
 var formlen=forms.length;
 for(var i=0;i<formlen;i++){
  var form=forms[i];
  var elems=form.elements;
  var elemlen=elems.length;
  for(var j=0;j<elemlen;j++){
   var elem=elems[j];
   if(elem.nodeName=="SELECT"&&elem.useXmlBinding&&elem.useXmlBinding=="true"&&elem.dataSource){
    initXmlMenu(elem,true);
   }
  }
 }
}
/**
* 绑定顶级菜单
*/
function initXmlMenu(elem,isInit){
 elem.options.length=0;
 var dataSource=elem.dataSource;
 var menuObj=CascadeMenuConfig[dataSource];
 var items=menuObj.items;
 var itemlen=items.length;
 for(var i=0;i<itemlen;i++){
  var optionlen=elem.options.length;
  var itemObj=items[i];
  var option=new Option(itemObj.display,itemObj.value);
  elem.options[elem.options.length]=option;
 }
 var subMenusStr=elem.subMenus;
 if(subMenusStr){//递归初始化子菜单
  var subMenuIds=subMenusStr.split(/[,|;]/);
  var subMenuLen=subMenuIds.length;
  for(var i=0;i<subMenuLen;i++){
   var subMenu=$(subMenuIds[i]);
   if(!subMenu){
    throw new Error("绑定select失败,没有这个子菜单:"+subMenuIds[i]);
   }
   initSubXmlMenu(elem,subMenu,isInit);
  }
 }
 if(isInit==true){
  elem.attachEvent("onchange",onXmlCascadeMenuChange);
  if(elem.selectedValue){//设置默认值
   elem.value=elem.selectedValue;
   elem.fireEvent("onchange");
  }
 }
}
/**
* 绑定子菜单
*/
function initSubXmlMenu(parent,elem,isInit){
 elem.options.length=0;
 var parentValue=parent.value;
 var dataSource=elem.dataSource;
 var menuObj=CascadeMenuConfig[dataSource];
 var items=menuObj.items;
 var itemlen=items.length;
 for(var i=0;i<itemlen;i++){
  var optionlen=elem.options.length;
  var itemObj=items[i];
  if(itemObj.parentValue!=parentValue){
   continue;
  }
  var option=new Option(itemObj.display,itemObj.value);
  elem.options[elem.options.length]=option;
 }
 var subMenusStr=elem.subMenus;
 if(subMenusStr){//递归初始化子菜单
  var subMenuIds=subMenusStr.split(/[,|;]/);
  var subMenuLen=subMenuIds.length;
  for(var i=0;i<subMenuLen;i++){
   var subMenu=$(subMenuIds[i]);
   if(!subMenu){
    throw new Error("绑定select失败,没有这个子菜单:"+subMenuIds[i]);
   }
   initSubXmlMenu(elem,subMenu);
  }
  if(isInit==true){
   elem.attachEvent("onchange",onXmlCascadeMenuChange);
  }
 }
 if(isInit==true){
  if(elem.selectedValue){//设置默认值
   elem.value=elem.selectedValue;
   elem.fireEvent("onchange");
  }
 }
}
/**
* 菜单onchange事件出发的动作
*/
function onXmlCascadeMenuChange(){
 var elem=event.srcElement;
 if(!elem)return;
 var subMenusStr=elem.subMenus;
 if(subMenusStr){//递归初始化子菜单
  var subMenuIds=subMenusStr.split(/[,|;]/);
  var subMenuLen=subMenuIds.length;
  for(var i=0;i<subMenuLen;i++){
   var subMenu=$(subMenuIds[i]);
   if(!subMenu){
    throw new Error("绑定select失败,没有这个子菜单:"+subMenuIds[i]);
   }
   initSubXmlMenu(elem,subMenu,false);
  }
 }
}

/**
* 封装javascript访问XML相关方法
*/
var XmlUtil=new Object();
XmlUtil.NULL=null;
/**
* 获得属性的值
*/
XmlUtil.getProperty=function(xmlNode,propertyName){
 var attrs=xmlNode.attributes;
 var attrlen=attrs.length;
 for(var i=0;i<attrlen;i++){
  var attr=attrs[i];
  if(attr.name==propertyName){
   return attr.value;
  }
 }
 return XmlUtil.NULL;
}


/**
* 级联菜单对应的内存对象
*/
function CascadeMenu(){
 this.items=new Array();
}
CascadeMenu.prototype.addItem=function(item){
 this.items.push(item);
}
/**
* 菜单Option对应的对象
*/
function CascadeMenuItem(){
 this.display=XmlUtil.NULL;
 this.value=XmlUtil.NULL;
 this.parentValue=XmlUtil.NULL;
}

 

原创粉丝点击