1.创建XML文档:cascaded_select.xml
2.创建BlueParseXML.js,用来加载解析XML文档
3.创建BlueCasadedSelect.js文件,用来生成级联下拉框
4.创建测试页面cascaded_select.html
http://blog.csdn.net/lip009/archive/2007/10/15/1826028.aspx
- <?xml version="1.0" encoding="GBK"?>
- <select>
- <province key="sx" value="陕西">
- <city key="xa" value="西安"/>
- <city key="bj" value="宝鸡"/>
- <city key="wn" value="渭南">
- <xian key="fp" value="富平">
- <zhen key="zq" value="张桥"/>
- </xian>
- </city>
- <city key="ak" value="安康"/>
- </province>
- <province key="js" value="江苏">
- <city key="nj" value="南京"/>
- <city key="xz" value="徐州"/>
- </province>
- <province key="sh" value="上海"/>
- </select>
2.创建BlueParseXML.js,用来加载解析XML文档
- /**
- * @description 解析并封装XML
- * @author BluesLee
- * @lastModif BluesLee
- * @createDate 2007-10-13
- * @modifDate 2007-10-15
- * @version 1.0
- */
- //解析XML文件对象构造器
- function BlueParseXML(){
- }
- BlueParseXML.prototype.xml;//定义对象属性xml
- BlueParseXML.prototype.loadFinish;//加载完成函数
- BlueParseXML.prototype.nodeProperties=new Array();//节点属性数组
- BlueParseXML.prototype.key="key";
- BlueParseXML.prototype.value="value";
- BlueParseXML.prototype.nodeList;//节点集合
- BlueParseXML.prototype.rootName;
- BlueParseXML.XML_NULL=-1;//未加载xml,或加载失败
- //加载xml文件
- BlueParseXML.prototype.loadXML=function(url){
- var newXML;
- var obj=this;
- //如果它受支持,采用标准的2级DOM技术
- if(document.implementation && document.implementation.createDocument){
- //创建新的Document对象
- newXML=document.implementation.createDocument("","",null);
- //设置装载完毕时触发事件
- newXML.οnlοad=function(){
- if(obj.loadFinish){
- obj.loadFinish();
- }
- }
- newXML.load(url);
- }else{//IE浏览器创建Document对象
- newXML=new ActiveXObject("Microsoft.XMLDOM");
- //设置onload
- newXML.onreadystatechange=function(){
- if(newXML.readyState==4){
- if(obj.loadFinish){
- obj.loadFinish();
- }
- }
- }
- newXML.load(url);
- }
- this.xml=newXML;
- }
- //解析遍历xml
- BlueParseXML.prototype.parseXML=function(){
- if(this.xml==null){
- alert("XML未加载,请先加载XML文件!");
- return parseXML.XML_NULL;
- }
- var rootNode=this.xml.documentElement;
- this.rootName=rootNode.tagName;
- this.nodeList=new ChildNodeList();
- this.level=this.iteratorNode(this.nodeList,rootNode,1);
- return this.level;
- }
- //遍历节点,将节点信息封装存入ChildNodeList中
- BlueParseXML.prototype.iteratorNode=function(list,node,level){
- if(!isNaN(level) && level>0){
- list.nodeLevel=level;
- }
- var result=list.nodeLevel;//节点级别
- var flag=true;//判断节点是否有子节点标记
- for(var child=node.firstChild;child!=null;child=child.nextSibling){
- flag=false;//有子节点
- if(list.nodeName==null || list.nodeName==""){
- list.nodeName=child.tagName;
- }
- if(list.nodeName==child.tagName){
- var nodeInfo=new NodeInfo();
- nodeInfo.nodeLevel=list.nodeLevel;//设置节点级别
- nodeInfo.nodeName=list.nodeName;//设置节点名称
- nodeInfo.key=child.getAttribute(this.key);//设置节点属性
- nodeInfo.value=child.getAttribute(this.value);
- for(var index=0;index<this.nodeProperties.length;index++){
- nodeInfo[this.nodeProperties[index]]=child.getAttribute(this.nodeProperties[index]);
- }
- list.addElement(nodeInfo.key,nodeInfo);//把节点加入父节点的子节点集合
- var n=this.iteratorNode(nodeInfo.childNodeList,child,list.nodeLevel+1);
- if(n>result){//如果子节点返回的节点级别大于改节点级别,设置返回节点级别为最大级别
- result=n;
- }
- }
- }
- if(flag){//当改节点没有子节点时返回的节点级别-1
- result=result-1;
- }
- return result;
- }
- //扩展String对象,增加trim方法去掉字符串前后空格
- String.prototype.trim=function(){
- return this.replace(/^s*/g,"").replace(/s*$/g,"");
- }
- /**//**
- * @description 自定义集合对象(利用对象属性键值对,类似Hashtable使用)
- * @author BluesLee
- * @lastModif BluesLee
- * @createDate 2007-10-13
- * @modifDate 2007-10-15
- * @version 1.0
- */
- ChildNodeList.prototype.nodeLevel=1;
- ChildNodeList.prototype.nodeName;
- ChildNodeList.prototype.keyArray;
- ChildNodeList.prototype.ELEMENT_NULL=-1;//元素为空
- ChildNodeList.prototype.ELEMENT_EXIST=-2;//元素已经存在
- ChildNodeList.prototype.ELEMENT_NOT_EXIST=-3;//元素不存在
- ChildNodeList.prototype.INDEX_OUT=-4//数组下标越界
- ChildNodeList.prototype.ERROR_DELETE=-5//删除元素出错
- function ChildNodeList(){
- this.keyArray=new Array();
- }
- //添加集合元素
- ChildNodeList.prototype.addElement=function(key,element){
- if(key==null || element==null){
- return ChildNodeList.ELEMENT_NULL;
- }
- if(this[key]!=null){
- return ChildNodeList.ELEMENT_EXIST;
- }
- var index=this.keyArray.length;
- this.keyArray[index]=key;
- this[key]=element;
- return index;
- }
- //根据下标删除集合元素
- ChildNodeList.prototype.deleteElementByIndex=function(index){
- if(index>=this.keyArray.length){
- return ChildNodeList.INDEX_OUT;
- }
- var key=this.keyArray[index];
- for(var i=index;i<this.keyArray.length;i++){
- this.keyArray[i]=this.keyArray[i+1];
- }
- this.keyArray.length=this.keyArray.length-1;
- delete this[key];
- return index;
- }
- //根据key删除集合元素
- ChildNodeList.prototype.deleteElementByKey=function(key){
- if(this[key]==null){
- return ChildNodeList.ELEMENT_NOT_EXIST;
- }
- for(var index=0;index<this.keyArray.length;index++){
- if(this.keyArray[index]==key){
- return this.deleteElementByIndex(index);
- }
- }
- return ChildNodeList.ERROR_DELETE;
- }
- //根据key查找元素
- ChildNodeList.prototype.getElementByKey=function(key){
- return this[key];
- }
- //根据下标查找元素
- ChildNodeList.prototype.getElementByIndex=function(index){
- return this.getElementByKey(this.keyArray[index]);
- }
- //获取集合大小
- ChildNodeList.prototype.size=function(){
- return this.keyArray.length;
- }
- /**//**
- * @description 节点信息封装对象
- * @author BluesLee
- * @lastModif BluesLee
- * @createDate 2007-10-13
- * @modifDate 2007-10-15
- * @version 1.0
- */
- NodeInfo.prototype.nodeLevel;
- NodeInfo.prototype.nodeName;//节点名称
- NodeInfo.prototype.key;//节点名称,对应xml节点key属性
- NodeInfo.prototype.value;//节点内容,对应xml节点value属性
- NodeInfo.prototype.childNodeList;//子节点列表,用ChildNodeList对象封装
- //构造器
- function NodeInfo(){
- this.childNodeList=new ChildNodeList();
- }
3.创建BlueCasadedSelect.js文件,用来生成级联下拉框
- /**
- * @description 级联下拉对象
- * @author BluesLee
- * @lastModif BluesLee
- * @createDate 2007-10-13
- * @modifDate 2007-10-15
- * @version 1.0
- */
- BlueCasadedSelect.prototype.selectList;
- BlueCasadedSelect.prototype.defaultValue="-1";
- BlueCasadedSelect.prototype.defaultText="请选择…";
- BlueCasadedSelect.prototype.nodeList;//节点总集合
- BlueCasadedSelect.prototype.isAddOnChangeEvent=false;
- BlueCasadedSelect.prototype.SELECTLIST_NULL=-1;//下拉对象数组为空
- BlueCasadedSelect.prototype.SELECTLIST_TYPE_NOT_ARRAY=-2;//下拉对象数组不是数组对象
- BlueCasadedSelect.prototype.SELECTLIST_EMPTY=-3;//下拉对象数组为空数组
- BlueCasadedSelect.prototype.SELECTLIST_LENGTH_OUT=-4;//下拉对象数组小于节点集合级别
- BlueCasadedSelect.prototype.NODELIST_EMPTY=-5;//节点集合为空
- BlueCasadedSelect.prototype.EVENT_NULL=-6;//事件源为空
- //构造器
- function BlueCasadedSelect(nodeList){
- if(nodeList!=null){
- this.nodeList=nodeList;
- }else{
- this.nodeList=new ChildNodeList();
- }
- }
- /**//**
- * 创建下拉列表
- * @author BluesLee
- * @lastModif BluesLee
- * @createDate 2007-10-13
- * @lastModifDate 2007-10-13
- * @param parentNode 下拉列表父节点对象
- * @param nameList 下拉列表名字集合[可选参数]
- * @version 1.0
- */
- BlueCasadedSelect.prototype.createSelect=function(parentNode,nameList){
- if(nameList==null){
- if(this.nodeList.size()>0){
- return this.createSelectDefault(parentNode,this.nodeList);
- }
- return this.NODELIST_EMPTY;
- }
- if(this.selectList==null){
- this.selectList=new Array();
- }
- this.selectList.length=nameList.length;
- var obj=this;
- for(var i=0;i<nameList.length;i++){
- var select=document.createElement("select");
- select.setAttribute("name",nameList[i]);
- select.setAttribute("id",nameList[i]);
- select.options.length=1;
- select.options[0].value=this.defaultValue;
- select.options[0].text=this.defaultText;
- if(i<nameList.length-1){
- select.attachEvent("onchange",function(){obj.changeSelect(select);});
- this.isAddOnChangeEvent=true;
- }
- this.selectList[i]=select;
- parentNode.appendChild(select);
- }
- return this.selectList.length;
- }
- /**//**
- * 创建下拉列表(默认创建方法)
- * @author BluesLee
- * @lastModif BluesLee
- * @createDate 2007-10-13
- * @lastModifDate 2007-10-13
- * @param parentNode 下拉列表父节点对象
- * @param nodeList XML文档节点集合
- * @version 1.0
- */
- BlueCasadedSelect.prototype.createSelectDefault=function(parentNode,nodeList){
- if(this.selectList==null){
- this.selectList=new Array();
- }
- var obj=this;
- if(nodeList!=null && nodeList.nodeName!=null){
- this.selectList.length=this.selectList.length+1;
- var select=document.createElement("select");
- select.setAttribute("name",nodeList.nodeName);
- select.setAttribute("id",nodeList.nodeName);
- select.options.length=1;
- select.options[0].value=this.defaultValue;
- select.options[0].text=this.defaultText;
- this.selectList[this.selectList.length-1]=select;
- parentNode.appendChild(select);
- for(var i=0;i<nodeList.size();i++){
- var childNodeList=nodeList.getElementByIndex(i).childNodeList;
- if(childNodeList.size()>0){
- select.attachEvent("onchange",function(){obj.changeSelect(select);});
- this.isAddOnChangeEvent=true;
- this.createSelectDefault(parentNode,childNodeList);
- break;
- }
- }
- }
- return this.selectList.length;
- }
- /**//**
- * 添加下拉列表onChange事件响应
- * @author BluesLee
- * @lastModif BluesLee
- * @createDate 2007-10-13
- * @lastModifDate 2007-10-13
- * @version 1.0
- */
- BlueCasadedSelect.prototype.addOnChangeEvent=function(){
- if(this.isAddOnChangeEvent){
- return;
- }
- if(this.selectList==null){
- return this.SELECTLIST_NULL;
- }
- if(this.selectList.constructor!=Array){
- return this.SELECTLIST_TYPE_NOT_ARRAY;
- }
- if(this.selectList.length<=0){
- return this.SELECTLIST_EMPTY;
- }
- var obj=this;
- for(var i=0;i<this.selectList.length-1;i++){
- var select=this.selectList[i];
- select.attachEvent("onchange",function(){obj.changeSelect(select);});
- }
- this.isAddOnChangeEvent=true;
- }
- /**//**
- * 初始化下拉列表
- * @author BluesLee
- * @lastModif BluesLee
- * @createDate 2007-10-13
- * @lastModifDate 2007-10-13
- * @param paramList 初始化每一级下拉默认选项参数列表
- * @param nodeList XML文档节点集合[可选参数]
- * @version 1.0
- */
- BlueCasadedSelect.prototype.init=function(paramList,nodeList){
- var currentList;
- if(nodeList==null){
- currentList=this.nodeList;
- }else{
- currentList=nodeList;
- }
- if(this.selectList==null){
- return this.SELECTLIST_NULL;
- }
- if(this.selectList.constructor!=Array){
- return this.SELECTLIST_TYPE_NOT_ARRAY;
- }
- if(this.selectList.length<=0){
- return this.SELECTLIST_EMPTY;
- }
- if(this.selectList.length<currentList.nodeLevel){
- return this.SELECTLIST_LENGTH_OUT;
- }
- if(currentList.size()<=0){
- return this.NODELIST_EMPTY;
- }
- var select=this.selectList[currentList.nodeLevel-1];
- var defaultValue=paramList[currentList.nodeLevel-1];
- for(var i=0;i<currentList.size();i++){
- var nodeInfo=currentList.getElementByIndex(i);
- var index=select.options.length;
- select.options.length=index+1;
- select.options[index].value=nodeInfo.key;
- select.options[index].text=nodeInfo.value;
- if(defaultValue!=null && defaultValue==nodeInfo.key){
- select.options[index].selected=true;
- if(nodeInfo.childNodeList.size()<=0){
- for(var j=currentList.nodeLevel;j<this.selectList.length;j++){
- var sel=this.selectList[j];
- var n=sel.options.length;
- sel.options.length=n+1;
- sel.options[n].value=nodeInfo.key;
- sel.options[n].text=nodeInfo.value;
- sel.options[n].selected=true;
- }
- }else{
- this.init(paramList,nodeInfo.childNodeList);
- }
- }
- }
- return select.options.length;
- }
- /**//**
- * 下拉列表联动
- * @author BluesLee
- * @lastModif BluesLee
- * @createDate 2007-10-13
- * @lastModifDate 2007-10-13
- * @param event 事件源下拉对象
- * @version 1.0
- */
- BlueCasadedSelect.prototype.changeSelect=function(event){
- if(event==null){
- return this.EVENT_NULL;
- }
- if(this.selectList==null){
- return this.SELECTLIST_NULL;
- }
- if(this.selectList.constructor!=Array){
- return this.SELECTLIST_TYPE_NOT_ARRAY;
- }
- if(this.selectList.length<=0){
- return this.SELECTLIST_EMPTY;
- }
- if(this.nodeList.size()<=0){
- return this.NODELIST_EMPTY;
- }
- var nextList=this.nodeList;
- var nextSelect=event;
- var flag=false;
- var n=0;
- for(var i=0;i<this.selectList.length;i++){
- var select=this.selectList[i];
- if(flag){
- this.selectList[i].options.length=1;
- }else{
- if(nextList.getElementByKey(select.value)!=null){
- nextList=nextList.getElementByKey(select.value).childNodeList;
- }else{
- nextList=new ChildNodeList();
- }
- }
- if(select==event){
- nextSelect=this.selectList[i+1];
- flag=true;
- n=i;
- }
- }
- if(nextList.size()<=0 && event.value!=this.defaultValue){
- for(var i=n+1;i<this.selectList.length;i++){
- nextSelect=this.selectList[i];
- var index=nextSelect.options.length;
- nextSelect.options.length=index+1;
- nextSelect.options[index].value=event.value;
- nextSelect.options[index].text=event.options[event.selectedIndex].text;
- nextSelect.options[index].selected=true;
- }
- return nextSelect.options.length;
- }
- for(var i=0;i<nextList.size();i++){
- var nodeInfo=nextList.getElementByIndex(i);
- var index=nextSelect.options.length;
- nextSelect.options.length=index+1;
- nextSelect.options[index].value=nodeInfo.key;
- nextSelect.options[index].text=nodeInfo.value;
- }
- return nextSelect.options.length;
- }
4.创建测试页面cascaded_select.html
- <!--深蓝忧郁级联下拉框-->
- <script src="BlueParseXML.js">
- //加载XML
- </script>
- <script src="BlueCasadedSelect.js">
- //生成级联下拉
- </script>
- <body>
- </body>
- <script>
- function finish(){
- alert("加载完成");
- }
- var myxml=new BlueParseXML();
- //添加xml加载完成事件响应
- myxml.loadFinish=finish;
- myxml.loadXML("cascaded_select.xml");
- var level=myxml.parseXML();
- //多级级联下拉
- var blueCasadedSelect=new BlueCasadedSelect(myxml.nodeList);
- //生成下拉列表,下拉列表name属性为xml节点名
- blueCasadedSelect.createSelect(document.body);
- //如果下拉列表提前已有,则不需生成,需要设置下拉列表集合为已有下拉集合,并添加onchange事件响应内容
- //blueCasadedSelect.selectList=sels;
- //blueCasadedSelect.addOnChangeEvent();
- blueCasadedSelect.init(new Array("sx","xa"));
- //简单的树结构遍历测试
- //====================================
- document.write("<br>");
- function iterator(list){
- if(list.size()<=0){
- return;
- }
- for(var i=0;i<list.size();i++){
- var obj=list.getElementByIndex(i);
- for(var j=1;j<list.nodeLevel;j++){
- document.write("——");
- }
- document.write("<a href='"+obj.key+"'>"+obj.nodeLevel+obj.value+"</a><br>");
- iterator(obj.childNodeList);
- }
- }
- iterator(myxml.nodeList);
- //====================================
- </script>
http://blog.csdn.net/lip009/archive/2007/10/15/1826028.aspx