如何基于第一个选择填充第二个选择菜单,基于第二个填充第三个选择菜单-使用Javascript

How to populate a second select menu based on the first selection and third based on second - Using Javascript

本文关键字:选择 填充 菜单 第二个 三个 Javascript 使用 第一个 何基于      更新时间:2023-09-26

我需要显示三个选择菜单来选择State、District和Area。其中第二选择菜单应基于第一选择菜单动态填充,第三选择菜单基于第二选择。

为此,我在Javascriptsource.com上找到了一个,并进行了一些替换以获得以下内容,

    <script>

    var districts = new Array();
    districts['Tamilnadu'] = new Array('Chennai','Coimbatore','Vellore');
    districts['Andhra Pradesh'] = new Array('Hyderabad','Andra 2','Andra 3');
    var cities = new Array();
    areas['Tamilnadu'] = new Array();
    areas['Tamilnadu']['Chennai'] = new Array('Kolathur','Perambur');
    areas['Tamilnadu']['Coimbatore'] = new Array('Combatore 1','Coimbatore 2');
    areas['Tamilnadu']['Vellore'] = new Array('Vellore 1','Vellore 2');
    areas['Andhra Pradesh'] = new Array();
    areas['Andhra Pradesh']['Hyderabad'] = new Array('Hyde 1','Hyde 2');
    areas['Andhra Pradesh']['Andra 2'] = new Array('Andra2 1','Andra2 2');
    areas['Andhra Pradesh']['Andra 3'] = new Array('Andra3 1','Andra3 2');
    function setDistrict() {
    stateSelect = document.getElementById('state');
    districtList = districts[stateSelect.value];
    changeSelect('district', districtList, districtList);
    setArea();
    }
    function setArea() {
    stateSelect = document.getElementById('state');
    districtSelect = document.getElementById('district');
    areaList = areas[stateSelect.value][districtSelect.value];
    changeSelect('area', areaList, areaList);
    }
    function changeSelect(fieldID, newOptions, newValues) {
    selectField = document.getElementById(fieldID);
    selectField.options.length = 0;
     for (i=0; i<newOptions.length; i++) {
     selectField.options[selectField.length] = new Option(newOptions[i], newValues[i]);
     }
    }
    // The below codes do what?
    function addLoadEvent(func) {
    var oldonload = window.onload;
     if (typeof window.onload != 'function') {
     window.onload = func;
     } else {
     window.onload = function() {
     if (oldonload) {
      oldonload();
     }
    func();
       }
      }
    }
    addLoadEvent(function() {
      setDistrict();
    });

    </script>

它工作得很好,除了当第二个选择菜单的值发生变化时,第三个选择菜单没有被填充。

哪里出了问题,我也想知道这是否适用于所有主要的浏览器?

有什么更好的解决方案吗?有人能解释一下(注释行之后(最后一块代码的实际作用吗?

提前谢谢。

[我确实在stackoverflow和其他地方搜索了答案。但似乎没有什么能帮助满足只使用javascript的需求。]

[更新]它现在正在工作。但是它能在所有浏览器上工作吗?有人能解释一下注释行后面的代码是怎么做的吗?

有几个问题。

  1. 看起来主要的问题是您没有在任何地方声明areas;而是声明cities

  2. 该代码还因未声明其变量而遭受隐式全局变量的恐怖

  3. 即使在声明其变量时,代码也会使它们成为全局变量。这里没有必要这样做,最好将整个过程封装在一个作用域函数中,以避免在(非常拥挤的(全局命名空间中发生冲突。看起来你一定在某个地方的HTML onXyz属性中使用了changeSelect,所以我们必须做一些事情来使其全局化(更好的答案是不使用HTML onXyz属性,而是在代码中的select元素上使用attachEvent(IE8和更早版本(或addEventListener(所有其他((我在下面没有尝试过这样做,我只是使changeSelect全局化(。

  4. 您询问"下面的代码[原文如此]做什么?"的代码试图等待调用setDistrict,直到HTML定义的select元素存在之后。但是该代码已经非常过时了。在20世纪90年代中期,如果你想在页面加载完成后运行一个函数,你可以将其分配给window.onload,或者将其作为<body onload="functionName();">放入打开的<body>标记中。其中可能只有一个,如果你再做一次,它会删除第一个。因此,该代码是尝试查看是否已经有一个,如果有,用新的替换它,但也调用它。

    幸运的是,在90年代末,微软在IE 5.5(5.0?(中引入了attachEvent,此后不久,我们就有了DOM2事件,它在所有其他浏览器中为我们提供了addEventListener,这两种浏览器都允许我们在不删除任何以前的处理程序的情况下做同样的事情。

    但是,这里不需要等待window load事件,这是个坏主意,因为它要在加载所有之后才会启动,包括所有图像。相反,我们只是将带有此代码的script元素放在HTML的最后,就在关闭</body>标记之前,并直接调用setDistrict()

    // Just make sure this script is referenced from a `script` element
    // at the **end** of the HTML, just before the closing `</body>` tag
    setDistrict();
    

    这些元素将在那时存在。没有理由再等了(window.onload要晚很多(。

  5. districtsareas(或一些area子元素(都不应该是数组。它们根本没有被用作数组,只是被用作对象。CCD_ 26和CCD_ 27的所有初始化都可以简单得多。

将所有这些放在一起,并使用一些适当的格式:

// Scoping function prevents the `vars` inside from being globals
(function() {
    // Create our districts and areas
    var districts = {
        "Tamilnadu": ["Chennai", "Coimbatore", "Vellore"],
        "Andhra Pradesh": ["Hyderabad", "Andra 2", "Andra 3"]
    };
    var areas = {
        "Tamilnadu": {
            "Chennai": ["Kolathur", "Perambur"],
            "Coimbatore": ["Combatore 1", "Coimbatore 2"],
            "Vellore": ["Vellore 1", "Vellore 2"]
        },
        "Andhra Pradesh": {
            "Hyderabad": ["Hyde 1", "Hyde 2"],
            "Andra 2": ["Andra2 1", "Andra2 2"],
            "Andra 3": ["Andra3 1", "Andra3 2"]
        }
    };
    function setDistrict() {
        // Note the use of `var` to make these variables local to the function
        var stateSelect = document.getElementById('state');
        var districtList = districts[stateSelect.value];
        changeSelect('district', districtList, districtList);
        setArea();
    }
    function setArea() {
        // Note the use of `var` to make these variables local to the function
        var stateSelect = document.getElementById('state');
        var districtSelect = document.getElementById('district');
        var areaList = areas[stateSelect.value][districtSelect.value];
        changeSelect('area', areaList, areaList);
    }
    // Make `changeSelect` available globally
    window.changeSelect = changeSelect;
    function changeSelect(fieldID, newOptions, newValues) {
        // Note the use of `var` to make these variables local to the function
        var i;
        var selectField = document.getElementById(fieldID);
        selectField.options.length = 0;
        for (i = 0; i < newOptions.length; i++) {
            selectField.options[selectField.length] = new Option(newOptions[i], newValues[i]);
        }
    }
    // Make sure this script is at the *end* of the HTML, just above the
    // closing </body> tag
    setDistrict();
})();

旁注:当谈到编程代码时,"代码"一词是一个像"水"一样的"大众名词"。它从来都不是复数。所以它总是"这个代码"而不是"这些代码"。