【实践】用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是数组其实那时候理解得不够清楚 刚好这几天看高程深刻理解了对象、构造函数以及闭包的原理后才有了更深刻的理解

原文地址:https://www.cnblogs.com/stitchgogo/p/6351789.html