案例描述

两个案例,分为左右移动元素与省市联动。如图所示

左右移动

省市联动

左右移动元素

左右移动案例很简单,思路大致如下:

  1. 获取当前点击的元素

  2. 移动元素

    • 单个

      将一个元素标签移动到右边

    • 全部

      将全部元素移动到右侧

在线演示:https://antmoe.gitee.io/project/2020/04/18/index.html

我们的html结构如下:

<div class="container">
    <select id="first" size="5" multiple>
        <option>Argentina</option>
        <option>Brazil</option>
        <option>Canada</option>
        <option>Chile</option>
        <option>China</option>
        <option>Cuba</option>
        <option>Denmark</option>
        <option>Egypt</option>
        <option>France</option>
        <option>Greece</option>
        <option>Spain</option>
    </select>
    <div class="btns">
        <button id="add">&gt;</button>
        <button id="add_all">&gt;&gt;</button>
        <button id="remove">&lt;</button>
        <button id="remove_all">&lt;&lt;</button>
    </div>
    <select id="second" size="5" multiple>

    </select>
</div>
  1. 实现移动单个

    实现的思路就是遍历左边容器里的每个选项,判断是否被选中(判断option.selected

    // 添加到右边
    var add = document.getElementById('add')
    add.onclick = function () {
        // 左边被选中的
        var first = document.getElementById('first')
        var options = first.getElementsByTagName('option')
        for (var i = 0; i < options.length; i++) {
            var option = options[i]
            if (option.selected) {
                // 移动到右边去
                var second = document.getElementById('second')
                second.appendChild(option)
            }
        }
    }
  2. 实现移动全部

    // 移动到右边
    var addAll = document.getElementById('add_all')
    addAll.onclick = function () {
        var first = document.getElementById('first')
        // HTMLCollection集合
        var options = first.getElementsByTagName('option')
        for (var i = 0; i < options.length; i++) {
            var option = options[i]
            var second = document.getElementById('second')
            second.appendChild(option)
        }
    }

    移动全部会遇到一个问题,我们通过first.getElementsByTagName('option')获取的内容,返回内容为一个动态集合,也就是说当移动一个元素后,这个集合的内容也就会发生变化。

    解决方案有两个

    • 第一种

      ①取到集合的总长度,并赋予变量

      ②循环的条件为小于这个变量

      ③循环取得值为第一项(固定)即options[0]

      var length = options.length
      for (var i = 0; i < length; i++) {
          var option = options[0]
      }
    • 第二种

      每一次循环完后循环的标志位减1即可。

      for (var i = 0; i < options.length; i++) {
          var option = options[i]
          i--
      }

    因此我们的最终的代码就变成了

    var addAll = document.getElementById('add_all')
    addAll.onclick = function () {
        var first = document.getElementById('first')
        // HTMLCollection集合
        var options = first.getElementsByTagName('option')
        // 1.具有11个元素,至少得11遍的循环
        var length = options.length
        for (var i = 0; i < options.length; i++) {
            var option = options[0]
            var second = document.getElementById('second')
            second.appendChild(option)
            i--
        }
    }

至于从右边移动到左边,思路基本相同。

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>左右移动效果</title>
        <style>
            .container {
                width: 400px;
                height: 200px;
                position: fixed;
                left: 50%;
                top: 50%;
                transform: translate(-50%, -50%);
            }

            .container select,
            .container .btns {
                display: block;
                float: left;
            }

            .container select {
                width: 40%;
                height: 100%;
            }

            .container select option {
                font-size: 22px;
            }

            .container .btns {
                width: 20%;
                height: 100%;
            }

            .container .btns button {
                display: block;
                width: 80%;
                height: 40px;
                margin: 8px auto;
            }
        </style>
    </head>

    <body>
        <div class="container">
            <select id="first" size="5" multiple>
                <option>Argentina</option>
                <option>Brazil</option>
                <option>Canada</option>
                <option>Chile</option>
                <option>China</option>
                <option>Cuba</option>
                <option>Denmark</option>
                <option>Egypt</option>
                <option>France</option>
                <option>Greece</option>
                <option>Spain</option>
            </select>
            <div class="btns">
                <button id="add">&gt;</button>
                <button id="add_all">&gt;&gt;</button>
                <button id="remove">&lt;</button>
                <button id="remove_all">&lt;&lt;</button>
            </div>
            <select id="second" size="5" multiple> </select>
        </div>
        <script>
            // 添加到右边
            var add = document.getElementById("add");
            add.onclick = function () {
                // 左边被选中的
                var first = document.getElementById("first");
                var options = first.getElementsByTagName("option");
                for (var i = 0; i < options.length; i++) {
                    var option = options[i];
                    if (option.selected) {
                        // 移动到右边去
                        var second = document.getElementById("second");
                        second.appendChild(option);
                    }
                }
            };
            // 移动到左边
            var remove = document.getElementById("remove");
            remove.onclick = function () {
                // 右边被选中的
                var second = document.getElementById("second");
                var options = second.getElementsByTagName("option");
                for (var i = 0; i < options.length; i++) {
                    var option = options[i];
                    if (option.selected) {
                        // 移动到左边去
                        var first = document.getElementById("first");
                        first.appendChild(option);
                    }
                }
            };
            // 移动到右边
            var addAll = document.getElementById("add_all");
            addAll.onclick = function () {
                var first = document.getElementById("first");
                // HTMLCollection集合
                var options = first.getElementsByTagName("option");
                // 1.具有11个元素,至少得11遍的循环
                var length = options.length;
                for (var i = 0; i < options.length; i++) {
                    var option = options[0];
                    var second = document.getElementById("second");
                    second.appendChild(option);
                    i--;
                }
            };
            // 移动到左边
            var addAll = document.getElementById("remove_all");
            addAll.onclick = function () {
                var second = document.getElementById("second");
                // HTMLCollection集合
                var options = second.getElementsByTagName("option");
                // 1.具有11个元素,至少得11遍的循环
                var length = options.length;
                for (var i = 0; i < options.length; i++) {
                    var option = options[i];
                    var first = document.getElementById("first");
                    first.appendChild(option);
                    i--;
                }
            };
        </script>
    </body>
</html>

省市联动案例

省市联动思路也较为简单,在线演示

  1. 界面加载完毕后,从数据里加载出数据
  2. 选择数据后,将对应的内容添加到市
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>省市联动</title>
</head>

<body>
    <label for="province">省份: </label>
    <select id="province">
        <option value="">---</option>
    </select>
    <label for="city">城市: </label>
    <select id="city">
        <option value="">---</option>
    </select>
    <script>
        // 声明数据
        var datas = [{
            'province': '河北省',
            'cities': ['石家庄市', '保定市', '邢台市', '唐山市', '秦皇岛市']
        },
        {
            'province': '山东省',
            'cities': ['青岛市', '济南市', '日照市', '威海市', '德州市']
        },
        {
            'province': '吉林省',
            'cities': ['长春市', '吉林市', '白城市', '松原市', '通化市']
        },
        {
            'province': '辽宁省',
            'cities': ['沈阳市', '大连市', '锦州市', '铁岭市', '朝阳市']
        },
        {
            'province': '黑龙江省',
            'cities': ['哈尔滨市', '齐齐哈尔市', '漠河市', '鹤岗市', '佳木斯市']
        }
        ]
        // 当页面加载完毕,省份信息显示在页面中
        var provinceElement = document.getElementById('province')
        // 遍历数据 并将每一个province添加
        for (var i = 0; i < datas.length; i++) {
            var data = datas[i]
            var provinceValue = data.province

            var optionElement = document.createElement('option')
            optionElement.textContent = provinceValue
            optionElement.setAttribute('value', provinceValue)

            provinceElement.appendChild(optionElement)
        }
        provinceElement.onchange = function () {
            // 先清空城市
            var cityElement = document.getElementById('city')
            var cityOptionElements = cityElement.getElementsByTagName('option')
            for (var y = 1; y < cityOptionElements.length; y++) {
                cityElement.removeChild(cityOptionElements[y])
                y--
            }
            // 获取用户点击的省份名
            var provinceInfo = provinceElement.value
            for (var j = 0; j < datas.length; j++) {
                // 取到每一个数据
                var data = datas[j]
                // 取到数据对应的省份
                console.log(data)
                var provinceData = data.province
                // 判断用户选择的哪个省份
                if (provinceInfo === provinceData) {
                    var cityDatas = data.cities
                    for (var x = 0; x < cityDatas.length; x++) {
                        var cityData = cityDatas[x]
                        var optionELement = document.createElement("option")
                        optionELement.textContent = cityData
                        optionELement.setAttribute("value", cityData)
                        cityElement.appendChild(optionELement)
                    }
                }

            }
        }
    </script>
</body>

</html>