如何在“选项组元素”中动态嵌套“选项元素”?

问题描述

const url = "https://restcountries.eu/rest/v2/all"

  fetch(url)
  .then(function(response){
    return response.json()
  })
  .then(function(data){
    console.log(data)
    worldRegion(data)
  })


  function worldRegion(myData) {
    var myArray = []
    for(var i = 0; i < myData.length; i++) {
      myArray.push(myData[i].region)
    }
    var region = myArray.filter(onlyUnique);
    var regionoptgroup = ""
    for(var i = 0; i < region.length; i++) {
      regionoptgroup += `<optgroup value=${region[i]} label="${region[i]}">${region[i]}</optgroup>`
    }
    document.querySelector("select").innerHTML = regionoptgroup
    const nodeList = document.querySelectorAll("optgroup")

    console.log(nodeList)

    var options  = ""
    for(var i = 0; i < myData.length; i++) {

      for(var j = 0; j < nodeList.length; j++) {
        if(myData[i].region === nodeList[j].value)
        options += `<option value="${myData[i].name}">${myData[i].name}</option>`
      }

    }
    document.querySelector("select").innerHTML = options

  }

  function onlyUnique(value,index,self) {
    return self.indexOf(value) === index;
  }
<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <Meta charset="utf-8">
    <title>what language do they speak</title>
  </head>
  <body>
    <select class="" name="">


    </select>

    <br>

  </body>
  <script src="index.js" type="text/javascript">

  </script>
</html>

我使用 for 循环创建了 6 个不同的 opt 组元素,即亚洲、欧洲、非洲、大洋洲、美洲和极地。然后我将有问题的 opt group 元素嵌套在 select 元素中。我还将元素或节点列表的选择存储在名为 nodeList 的变量中。

我正在尝试复制一种或多或少相似的方法,以便根据一个国家所属的地区将 option 元素嵌套在 opt 组元素中。因此,带有 InnerHTML Singapore 和“value = Asia”的 option 元素将嵌套在 Asia opt 组元素中。对于 250 个选项元素,依此类推。

我一直试图做的是提取每个选项组元素的值,以便相应地嵌套我的选项元素。因此,我的 if 语句中有以下条件:(=myData[i].region === nodeList[j].value)。但是,控制台也会抛出以下错误:“index.js:34 Uncaught (in promise) TypeError: Cannot read property 'value' of undefined at worldRegion (index.js:34) at index.js:10”

然后它就变成了意大利面条式的代码

我试图尽可能清楚地说明问题。但是,如果您需要进一步说明,请随时发表评论

我知道我可能需要处理缩进和优雅,但首先我希望我的代码能够工作

const url = "https://restcountries.eu/rest/v2/all"

  fetch(url)
  .then(function(response){
    return response.json()
  })
  .then(function(data){
    console.log(data)
    worldRegion(data)
  })


  function worldRegion(myData) {
    var myArray = []
    for(var i = 0; i < myData.length; i++) {
      myArray.push(myData[i].region)
    }
    var region = myArray.filter(onlyUnique);
    var regionoptgroup = ""
    for(var i = 0; i < region.length; i++) {
      regionoptgroup += `<optgroup value=${region[i]} label="${region[i]}">${region[i]}</optgroup>`
    }
    document.querySelector("select").innerHTML = regionoptgroup
    const nodeList = document.querySelectorAll("optgroup")

    console.log(nodeList)

    var options  = ""
    for(var i = 0; i < myData.length; i++) {

      for(var j = 0; j < nodeList.length; j++) {
      }
      if(myData[i].region === nodeList[j].value)
      options += `<option value="${myData[i].name}">${myData[i].name}</option>`
    }
    document.querySelector("select").innerHTML = options

  }

  function onlyUnique(value,self) {
    return self.indexOf(value) === index;
  }
<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <Meta charset="utf-8">
    <title>what language do they speak</title>
  </head>
  <body>
    <select class="" name="">


    </select>

    <br>

  </body>
  <script src="index.js" type="text/javascript">

  </script>
</html>

解决方法

您可以使用 DOM 方法而不是 HTML 创建 optgroup 元素,以便您立即获得对每个创建元素的引用。将这些元素存储在以区域名称为键的 Map 中。

然后,当您最终创建选项时,您可以在该 Map 中查找区域以检索对相应 optgroup 元素的引用:

const url = "https://restcountries.eu/rest/v2/all";

(async () => {
    const response = await fetch(url);
    const data = await response.json();
    let select = document.querySelector("select");
    // Create a map,keyed by region
    let regions = new Map(data.map(({region}) => [region,null]));
    // Assign an optgroup to each region in that map
    for (let region of regions.keys()) {
        let optgroup = document.createElement("optgroup");
        optgroup.setAttribute("value",region);
        optgroup.setAttribute("label",region || "(blank)");
        select.appendChild(optgroup);
        regions.set(region,optgroup);
    }
    for (let country of data) {
        // Create an option for each country
        let option = document.createElement("option");
        option.setAttribute("value",country.name);
        option.textContent = country.name;
        // Append it to the relevant optgroup
        regions.get(country.region).appendChild(option);
    }
})();
<select class="" name="">
</select>

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...