分享

js实现多级联动下拉框

 krrish 2010-07-07

花了半天时间实现一个多级联动下拉框,目的是对某一植物进行“门纲目科属”的归类。使用的技术是javascript+xml,之所以不用数据库,一来这方面的数据虽然量大但都是固定不变的,二来不希望加重服务器的负担,第三是因为这种多级从属关系的数据不太适合放在数据库里。

这是大概的思路:
1、读取xml文件
2、当一个下拉框选中某选项时,根据该选项,当前节点指向下一层,进入下一层下拉框的设置
3、取消当前下拉框的禁用,禁用下一层的下拉框
4、清空当前下拉框的选项
5、根据当前节点读取xml的数据,设置下拉框选项
6、返回步骤2

代码:
JavaScript

Javascript代码 复制代码
  1. //载入xml文件   
  2. var xmlDoc=new ActiveXObject("Microsoft.XMLDOM");   
  3. xmlDoc.async = false;   
  4. xmlDoc.load("classify.xml");   
  5.   
  6. var currentNode;//当前所在节点   
  7.   
  8. //读取xml文件数据并设置门、纲、目、科、属的下拉框   
  9.   
  10. //设置“门”的下拉框   
  11. function setPhylum(){   
  12.     currentNode=xmlDoc.documentElement;   
  13.     var phylums = currentNode.childNodes;   
  14.     for(var i=0;i<phylums.length;i++){   
  15.         //从门到属,都有name属性标签,并且所有下拉框选项索引都是从1开始   
  16.         var phylumName=phylums(i).selectNodes("name")(0).text;   
  17.         document.forms[0].phylum.options[i+1]=new Option(phylumName,phylumName);   
  18.     }   
  19. }   
  20.   
  21. //设置“纲”的下拉框   
  22. function setClazz(selectedIndex){   
  23.     //取消下拉框的禁用   
  24.     //后面的下拉框禁用,这是因应各下拉框的无序选择可能产生的错误   
  25.     //比如选了“科”又回头重新选“目”,或更改同一个下拉框选项)   
  26.     document.forms[0].clazz.disabled=null;   
  27.     document.forms[0].order.disabled="disabled";   
  28.     document.forms[0].family.disabled="disabled";   
  29.     document.forms[0].genus.disabled="disabled";   
  30.        
  31.     //将选中的门节点作为当前节点,注意这里需要将索引回减1   
  32.     //因为门的父节点没有name属性标签,而下拉框的索引又是从1开始   
  33.     //currentNode的赋值应使用绝对定位,也是因应各下拉框的无序选择   
  34.     //currentNode=currentNode.childNodes(selectedIndex-1);   
  35.     currentNode=xmlDoc.documentElement.childNodes(selectedIndex-1);   
  36.     var clazzes=currentNode.childNodes;   
  37.        
  38.     clearOption(document.forms[0].clazz);   
  39.     //因为门节点的第一个子节点为name属性标签,故循环时索引从1开始   
  40.     //相应的下拉框的索引就与纲节点的索引同步(不需要options[i+1]),目、科、属也是一样   
  41.     for(var i=1;i<clazzes.length;i++){   
  42.         var clazzName=clazzes(i).selectNodes("name")(0).text;   
  43.         document.forms[0].clazz.options[i]=new Option(clazzName,clazzName);   
  44.     }   
  45. }   
  46.   
  47. //设置“目”的下拉框   
  48. function setOrder(selectedIndex){   
  49.     //取消下拉框的禁用   
  50.     //后面的下拉框禁用,这是因应各下拉框的无序选择可能产生的错误(比如选了“科”又回头重新选“目”)   
  51.     document.forms[0].order.disabled=null;   
  52.     document.forms[0].family.disabled="disabled";   
  53.     document.forms[0].genus.disabled="disabled";   
  54.        
  55.     //currentNode的赋值应使用绝对定位   
  56.     var phylumSI=document.forms[0].phylum.selectedIndex;    //phylum selected index   
  57.     currentNode=xmlDoc.documentElement   
  58.         .childNodes(phylumSI-1)   
  59.         .childNodes(selectedIndex);   
  60.     var orders=currentNode.childNodes;   
  61.     clearOption(document.forms[0].order);   
  62.     for(var i=1;i<orders.length;i++){   
  63.         var orderName=orders(i).selectNodes("name")(0).text;   
  64.         document.forms[0].order.options[i]=new Option(orderName,orderName);   
  65.     }   
  66. }   
  67.   
  68. //设置“科”的下拉框   
  69. function setFamily(selectedIndex){   
  70.     document.forms[0].family.disabled=null;//取消下拉框的禁用   
  71.     document.forms[0].genus.disabled="disabled";//后面的下拉框禁用   
  72.        
  73.     //currentNode的赋值应使用绝对定位   
  74.     var phylumSI=document.forms[0].phylum.selectedIndex;//phylum selected index   
  75.     var clazzSI=document.forms[0].clazz.selectedIndex;  //clazz selected index   
  76.     currentNode=xmlDoc.documentElement   
  77.         .childNodes(phylumSI-1)   
  78.         .childNodes(clazzSI)   
  79.         .childNodes(selectedIndex);   
  80.     var families=currentNode.childNodes;   
  81.     clearOption(document.forms[0].family);   
  82.     for(var i=1;i<families.length;i++){   
  83.         var familyName=families(i).selectNodes("name")(0).text;   
  84.         document.forms[0].family.options[i]=new Option(familyName,familyName);   
  85.     }   
  86. }   
  87.   
  88. //设置“属”的下拉框   
  89. function setGenus(selectedIndex){   
  90.     document.forms[0].genus.disabled=null;//取消下拉框的禁用   
  91.        
  92.     //currentNode的赋值应使用绝对定位   
  93.     var phylumSI=document.forms[0].phylum.selectedIndex;//phylum selected index   
  94.     var clazzSI=document.forms[0].clazz.selectedIndex;  //clazz selected index   
  95.     var orderSI=document.forms[0].order.selectedIndex;  //order selected index   
  96.     currentNode=xmlDoc.documentElement   
  97.         .childNodes(phylumSI-1)   
  98.         .childNodes(clazzSI)   
  99.         .childNodes(orderSI)   
  100.         .childNodes(selectedIndex);   
  101.     var genuses=currentNode.childNodes;   
  102.     clearOption(document.forms[0].genus);   
  103.     for(var i=1;i<genuses.length;i++){   
  104.         //属为叶节点   
  105.         var genusName=genuses(i).text;   
  106.         document.forms[0].genus.options[i]=new Option(genusName,genusName);   
  107.     }   
  108. }   
  109.   
  110. //清空下拉框选项   
  111. function clearOption(selectElement){   
  112.     for(var i=1;i<selectElement.options.length;i++){   
  113.         selectElement.options[i]=null;   
  114.     }   
  115. }  



html

Html代码 复制代码
  1. <form id="plantForm" action="plant" method="post">  
  2.         <select id="phylum" name="plantForm.phylum"  
  3.             onchange="setClazz(this.selectedIndex)">  
  4.             <option selected="selected">———门———</option>  
  5.         </select>  
  6.            
  7.         <select id="clazz" name="plantForm.clazz" disabled="disabled"    
  8.             onchange="setOrder(this.selectedIndex)">  
  9.             <option selected="selected">———纲———</option>  
  10.         </select>  
  11.            
  12.         <select id="order" name="plantForm.order" disabled="disabled"    
  13.             onchange="setFamily(this.selectedIndex)">  
  14.             <option selected="selected">———目———</option>  
  15.         </select>  
  16.            
  17.         <select id="family" name="plantForm.family" disabled="disabled"    
  18.             onchange="setGenus(this.selectedIndex)">  
  19.             <option selected="selected">———科———</option>  
  20.         </select>  
  21.            
  22.         <select id="genus" name="plantForm.genus" disabled="disabled">  
  23.             <option selected="selected">———属———</option>  
  24.         </select>  
  25. </form>  
  26. <script type="text/javascript">  
  27.         setPhylum();//设置第一个下拉框   
  28. </script>  



最后是xml文件的内容

Xml代码 复制代码
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <plant>  
  3.     <phylum>  
  4.         <name>被子植物门</name>  
  5.         <clazz>  
  6.             <name>双子叶植物纲</name>  
  7.             <order>  
  8.                 <name>菊目</name>  
  9.                 <family>  
  10.                     <name>菊科</name>  
  11.                     <genus>菊属</genus>  
  12.                 </family>  
  13.                 <family>  
  14.                     <name>桔梗科</name>  
  15.                     <genus>同钟花属</genus>  
  16.                     <genus>刺萼参属</genus>  
  17.                 </family>  
  18.             </order>  
  19.             <order>  
  20.                 <name>胡椒目</name>  
  21.                 <family>  
  22.                     <name>胡椒科</name>  
  23.                     <genus>胡椒属</genus>  
  24.                     <genus>草胡椒属</genus>  
  25.                     <genus>齐头绒属</genus>  
  26.                 </family>  
  27.             </order>  
  28.         </clazz>  
  29.     </phylum>  
  30.     <phylum>  
  31.         <name>蕨类植物门</name>  
  32.         <clazz>  
  33.             <name>石松纲</name>  
  34.             <order>  
  35.                 <name>石松目</name>  
  36.                 <family>  
  37.                     <name>石松科</name>  
  38.                     <genus>石松属</genus>  
  39.                 </family>  
  40.             </order>  
  41.         </clazz>  
  42.     </phylum>  
  43. </plant>  

 

可以实现上下级下拉框的联动,支持无序选择,若向上重新选择,下下层下拉框将自动被禁用,下层下拉框选项也会相应改变。


有一点不足是,因为数据量实在太大,这样5个下拉框仍然可能出现某下拉框有几百甚至几千个选项,此时就失去了下拉框的意义,因此正在考虑是否应该做成输入框的形式,或者像搜索引擎那样带有输入提示功能,研究中,欢迎拍砖。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多