【问题标题】:How to populate a second select menu based on the first selection and third based on second - Using Javascript如何根据第一个选择和第三个基于第二个选择填充第二个选择菜单 - 使用 Javascript
【发布时间】:2014-08-16 00:14:14
【问题描述】:

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

为此, 我在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 的需求似乎没有任何帮助。 ]

[更新]它现在正在工作。但是它适用于所有浏览器吗?谁能解释一下注释行之后的代码是做什么的?

【问题讨论】:

  • var cities = new Array(); 是指var areas = new Array(); 吗?我没有看到你在任何地方声明areas,或在任何地方使用cities
  • 该死!是的,应该是地区而不是城市。谢谢,我去看看。
  • 它现在可以工作了,但它在所有浏览器上的工作方式都一样吗..?
  • 我想我现在已经完全回答了这个问题,抱歉,我最初错过了关于 onload 的内容。

标签: javascript html dynamic drop-down-menu


【解决方案1】:

那里有几个问题。

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

  2. 代码也因未声明其变量而遭受The Horror of Implicit Globals 的影响。

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

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

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

    但是这里没有必要等待windowload 事件,这是一个坏主意,因为它在所有内容加载后才会触发,包括您的所有图像。相反,我们只是将带有此代码的 script 元素放在 HTML 的最后,就在结束 &lt;/body&gt; 标记之前,然后直接调用 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 子元素)都不应该是数组。它们根本没有被用作数组,就像对象一样。 districtsareas 的所有初始化都可以简单得多

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

// 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();
})();

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

【讨论】:

  • @tjcrowder 谢谢...你能说一下注释行后面的代码实际上是做什么的吗...?它存在的目的是什么……?
  • @Saravanan:我会为答案添加解释。
  • 谢谢!我希望我得到了你所有的答案,但最后还有一个问题,代码是否在所有浏览器中都兼容?
  • @Saravanan:是的,据我所知,更新options 的方法适用于所有方面。
  • 非常感谢您帮助我解决这个问题。我希望搜索此代码的人会发现这很有用。
猜你喜欢
  • 1970-01-01
  • 2021-12-11
  • 2016-11-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-30
  • 1970-01-01
  • 2023-03-14
相关资源
最近更新 更多