【实践】用for-in 循环实现三联联动
之前用jq 做过一次三联联动以及四联联动
现在为了更好地了解对象用js的原生方式做了一次
*本节要点方法:
obj.selectedIndex 获取下拉列表选中的option 的索引
obj.options[obj.selectedIndex].text 获取对应下标option的文本值
obj.onchange =function(){} 下拉列表选中option更改事件
知道这些方法之后我们就可以开始动手了
下面是html代码
<select id="provin"> <option>请选择省</option> </select> <select id="city"> <option>请选择市</option> </select> <select id="area"> <option>请选择区/县</option> </select>
js代码:
注释应该能够很好地说明了
<script type="text/javascript"> window.onload = function(){ //建一个 data对象此对象里面有三个省名的属性 //各个省名的属性又有几个对应市名的属性 //各个市名属性的值包含着对应的区/县名 var data = { 广东省:{ 广州市:"荔湾区,越秀区,海珠区,天河区,芳村区,白云区,黄埔区,番禺市,花都市,增城市,从化市", 深圳市:"罗湖区,福田区,南山区,宝安区,龙岗区,盐田区", 珠海市:"香洲区,斗门区,金湾区", 湛江市:"赤坎区,霞山区,坡头区,麻章区,竹溪县,徐闻县,廉江市,雷州市,吴川市" }, 河北省:{ 石家庄市:"深泽县,无极县,赵县", 唐山市:"玉田县,遵化市,迁安市" }, 山东省:{ 济南市:"历下区,市中区,槐荫区,天桥区,历城区,长清县,平阴县,济阳县,商河县,章丘市", 青岛市:"市南区,市北区,四方区,黄岛区,崂山区,李沧区,城阳区" } } var provin = document.getElementById('provin'); var city = document.getElementById('city'); var area = document.getElementById('area'); var provinDefaultTxt = provin.options[0].text; var cityDefaultTxt = city.options[0].text; var areaDefaultTxt = area.options[0].text; //获取三个下拉列表元素以及他们的默认值 //开始循环遍历对象data for(key in data){ var newElemForPro = document.createElement("option"); var newProElemTxt = document.createTextNode(key); newElemForPro.setAttribute("value",key); newElemForPro.appendChild(newProElemTxt); provin.appendChild(newElemForPro); //把遍历出来的省份名添加到第一个下拉列表中 //当省份下拉列表变化时 provin.onchange = function(){ //获取选中option的索引 var provinSelectedIndex = this.selectedIndex; //通过选中option的索引找到 option的文本内容 var provinSelectedText = this.options[provinSelectedIndex].text; //在data数组里面找到对应的键 并将其值赋值给另外一个变量(通过键值对的形式返回出一个对象) var CityObject = data[provinSelectedText]; //清空city下拉列表的内容 city.options.length = 0; //如果选中了默认值其他两个下拉列表都会变为默认值 if (provinSelectedText == provinDefaultTxt) { area.options.length = 0; var cityNewElem = document.createElement("option"); var cityTxt = document.createTextNode(cityDefaultTxt); var areaNewElem = document.createElement("option"); var areaTxt = document.createTextNode(areaDefaultTxt); cityNewElem.appendChild(cityTxt); city.appendChild(cityNewElem); areaNewElem.appendChild(areaTxt); area.appendChild(areaNewElem); } //把对应省份的市名对象遍历一次 for(cityKey in CityObject){ var CityElem = document.createElement("option"); var CityElemTxt = document.createTextNode(cityKey); CityElem.appendChild(CityElemTxt); CityElem.setAttribute("value",cityKey); city.appendChild(CityElem); //把遍历出来的城市名添加到第二个下拉列表中 } //然后这里也是一样 获取选中的城市名索引 var citySelectedIndex = city.selectedIndex; //根据这个索引找到选中 option的文本值 var citySelectedText = city.options[citySelectedIndex].text; //通过这个市名的值找到对应的对象然后赋值给一个变量 //因为区/县名是一个字符串所以用 split() 方法将他们以逗号分隔变成一个数组 var areaObject = CityObject[citySelectedText].split(","); //将第三个下拉框清空 area.options.length = 0; //运用闭包模拟块级作用域 循环中的变量不会永远保存 (function(){ //遍历区/县数组添加到第三个下拉框中 for(var i = 0; i < areaObject.length; i++){ var areaElem = document.createElement("option"); var areaElemTxt = document.createTextNode(areaObject[i]); areaElem.appendChild(areaElemTxt); areaElem.setAttribute("value",areaObject[i]); area.appendChild(areaElem); } })(); //当市名下列列表发生变化的时候 city.onchange = function(){ //此时 citySelectedIndex 和 citySelectedText 变量已存在 //将他们直接获取新值就可以了不用再重新声明 citySelectedIndex = city.selectedIndex; citySelectedText = city.options[citySelectedIndex].text; //清空区/县下拉列表内容 area.options.length = 0; //根据选中的市名取出对应的区/县名 //同理调用split() 方法变成数组 areaObject = CityObject[citySelectedText].split(","); (function(){ //遍历数组 添加到区/县下拉列表中 for(var i = 0; i < areaObject.length; i++){ var areaElem = document.createElement("option"); var areaElemTxt = document.createTextNode(areaObject[i]); areaElem.appendChild(areaElemTxt); areaElem.setAttribute("value",areaObject[i]); area.appendChild(areaElem); } })(); } } } } </script>
还要说一下以前jq的联动笔记说data是数组其实那时候理解得不够清楚 刚好这几天看高程深刻理解了对象、构造函数以及闭包的原理后才有了更深刻的理解