本来最近在学习ajax,学着学着学到html——js——ajax,踏踏实实学习真好,布置于在做项目的时候,看不懂这个,看不懂那个,今天就跟大家谈谈这个小demo,两级联动,其实三级联动也好做,有空再做吧,自己以后要是用到了,也能看看。当然现在有好多的人或者公司已经这个玩意,写了一遍有一遍,完善了一遍又一遍,学习或者以后工作,总不能拿别人的就用,处理问题,也搞不定那个最烦人,还是自己了解一点好。
- 效果图
首先这个做的比较简陋,我只是想表达关于这个二级联动的实现方法,对于入门级的人也挺好
二、实现源码
//页面代码 <body> <div> <table> <tr> <td>所在省份</td> <td><select id="province" name="province"> <option value="">请选择省....</option> </select> </td> <td>所在市区</td> <td><select id="city" name="city"> <option value="">请选择市.....</option> </select> </td> </tr> </table> </div> </body> |
<script language="JavaScript"> window.onload = function() { //页面加载的时候开始读取xml文件 var xmlDoc = getxmlDoc("Provinces.xml"); var provinceXmlElements = xmlDoc.getElementsByTagName("Province"); var provinceElement = document.getElementById("province"); for (var i = 0; i < provinceXmlElements.length; i++) { var provinceXmlElement = provinceXmlElements[i]; var nameAttr = provinceXmlElement.getAttribute("ProvinceName"); var provinceOptions = document.createElement("option"); var optionsText = document.createTextNode(nameAttr); provinceOptions.setAttribute("value", nameAttr); provinceOptions.appendChild(optionsText); provinceElement.appendChild(provinceOptions); } //当下拉框中值改变时 document.getElementById("province").onchange = function() { //当下拉列表改变时,获取选中的值 var htmlValue = this.value; var cityElement = document.getElementById("city"); var oldOptionElements = cityElement.getElementsByTagName("option"); for (var i = oldOptionElements.length - 1; i > 0; i--) { cityElement.removeChild(oldOptionElements[i]); }
//读取配置文件 var xmlDoc = getxmlDoc("Provinces.xml"); //获取所有的省标签 var provinceXmlElements = xmlDoc.getElementsByTagName("Province");
var provinceElement = null;
// alert(provinceXmlElements.length); for (var i = 0; i < provinceXmlElements.length; i++) { var provinceXmlElement = provinceXmlElements[i]; var nameAttr = provinceXmlElement.getAttribute("ProvinceName"); if (nameAttr == htmlValue) { provinceElement = provinceXmlElement; } }
if (provinceElement != null) { var cityXmlElements = provinceElement .getElementsByTagName("city"); for (var i = 0; i < cityXmlElements.length; i++) { var cityValue = cityXmlElements[i].firstChild.nodeValue; var optionElement = document.createElement("option"); optionElement.setAttribute("cityValue", cityValue); var optionTextElement = document.createTextNode(cityValue); optionElement.appendChild(optionTextElement);
cityElement.appendChild(optionElement); } } } /** * 跨浏览器的解析xml文件的函数 * @param {Object} fileXmlName */ function getxmlDoc(xmlFile) { var xmlDoc; if (window.ActiveXObject) { xmlDoc = new ActiveXObject('Microsoft.XMLDOM');//IE xmlDoc.async = false; xmlDoc.load(xmlFile); } else if (isFirefox=navigator.userAgent.indexOf("Firefox")>0) { //火狐
xmlDoc = document.implementation.createDocument('', '', null); xmlDoc.load(xmlFile); } else{ //谷歌 var xmlhttp = new window.XMLHttpRequest(); xmlhttp.open("GET",xmlFile,false); xmlhttp.send(null); if(xmlhttp.readyState == 4){ xmlDoc = xmlhttp.responseXML.documentElement; } }
return xmlDoc; } } </script> |
- 实现原理
(1)首先准备好xml文件,省市县,固定的省对应固定的市,固定的市对应固定的县。
(2)开始解析你准备好的xml文件(其实这里你如果将基础学的比较扎实,其实读取xml文件就是读取它对应的节点、对应的文本属性、文本内容,其实xml最初就是想取代html,无奈html越来越火,无法取代,所以xml就开启了它无尽的配置之路)
指定代码:解析xml文件,在此之前我写的不支持谷歌和火狐,所以我就上网去找到了兼容的xml解析方法(一下就是,可以直接用)
/** * 跨浏览器的解析xml文件的函数 * @param {Object} fileXmlName */ function getxmlDoc(xmlFile) { var xmlDoc; if (window.ActiveXObject) { xmlDoc = new ActiveXObject('Microsoft.XMLDOM');//IE xmlDoc.async = false; xmlDoc.load(xmlFile); } else if (isFirefox=navigator.userAgent.indexOf("Firefox")>0) { //火狐
xmlDoc = document.implementation.createDocument('', '', null); xmlDoc.load(xmlFile); } else{ //谷歌 var xmlhttp = new window.XMLHttpRequest(); xmlhttp.open("GET",xmlFile,false); xmlhttp.send(null); if(xmlhttp.readyState == 4){ xmlDoc = xmlhttp.responseXML.documentElement; } } return xmlDoc; } } |
(2)在页面加载之前读取一次xml加载所有的省份,并把所有的省份通过dom技术附加在selected(技术如下:如有疑问请联系我),在此处解释一下关于window.onload = function(){},只有当页面中所有资源加载完毕之后,才执行大括号里面的代码
//页面加载的时候开始读取xml文件 var xmlDoc = getxmlDoc("Provinces.xml"); var provinceXmlElements = xmlDoc.getElementsByTagName("Province"); var provinceElement = document.getElementById("province"); for (var i = 0; i < provinceXmlElements.length; i++) { var provinceXmlElement = provinceXmlElements[i]; var nameAttr = provinceXmlElement.getAttribute("ProvinceName"); var provinceOptions = document.createElement("option"); var optionsText = document.createTextNode(nameAttr); provinceOptions.setAttribute("value", nameAttr); provinceOptions.appendChild(optionsText); provinceElement.appendChild(provinceOptions); } |
以上解决所有省份加入下拉列表
当我们点击不同省份,城市下拉列表显示该省所属的城市
解析方法:
(1)添加监听事件,获取省份改变的值;
document.getElementById("province").οnchange= function() { var htmlValue = this.value; } |
(2)同样通过xml解析出所有省份,改变的值与解析出的某一省份相同,将该省份设置成全局变量,然后通过该省的名称获取其孩子节点(即城市节点)
//读取配置文件 var xmlDoc = getxmlDoc("Provinces.xml"); //获取所有的省标签 var provinceXmlElements = xmlDoc.getElementsByTagName("Province"); //设置全局变量 var provinceElement = null; //alert(provinceXmlElements.length); //遍历每一个省份 for (var i = 0; i < provinceXmlElements.length; i++) { var provinceXmlElement = provinceXmlElements[i]; var nameAttr = provinceXmlElement.getAttribute("ProvinceName"); //比对改变值与解析出相同的省份 if (nameAttr == htmlValue) { provinceElement = provinceXmlElement; } } |
(3)遍历属于该省份所有城市节点,并经该节点数组一个一个添加在城市下拉列表中
if (provinceElement != null) { var cityXmlElements = provinceElement .getElementsByTagName("city"); for (var i = 0; i < cityXmlElements.length; i++) { var cityValue = cityXmlElements[i].firstChild.nodeValue; var optionElement = document.createElement("option"); optionElement.setAttribute("cityValue", cityValue); var optionTextElement = document.createTextNode(cityValue); optionElement.appendChild(optionTextElement); cityElement.appendChild(optionElement); } } |
当然目前我还未整理县和区,所以只做了两级联动,其实根本方法与此相同,不过大神们做的更牛逼的联动,也是我追求的梦想与方向,欢迎批评指点!!!
(4)当然在每次加载城市之后换其他省份时,我们需要将之前的省份所属城市删除
var cityElement = document.getElementById("city"); var oldOptionElements = cityElement.getElementsByTagName("option"); for (var i = oldOptionElements.length - 1; i > 0; i--) { cityElement.removeChild(oldOptionElements[i]); } |
如果有需要省市文档xml的,请下方留言,完全免费!!!