从嵌套对象创建无序列表树-JavaScript

时间:2020-05-11 09:07:53

标签: javascript html list object dom

我有一个这样的嵌套对象:

const countries = {
  "Europe": {
    "France": {},
    "Spain": {}
  },
  "America": {
    "North": {
      "USA": {},
      "Canada": {}
    },
    "South": {
      "Brazil": {},
      "Argentina": {}
    }
  }
};

我想像这样从中创建一个无序列表:

<ul>
  <li>
    Europe:
    <ul>
      <li>France</li>
      <li>Spain</li>
    </ul>
  </li>
  <li>
    America:
    <ul>
      <li>
        North:
        <ul>
          <li>USA</li>
          <li>Canada</li>
        </ul>
      </li>
      <li>
        South:
        <ul>
          <li>Brazil</li>
          <li>Argentina</li>
        </ul>
      </li>
    </ul>
  </li>
</ul>

并且最后不应该有任何空列表。

到目前为止,我尝试了这种递归方法,但是它只返回包含2个项[object Object]的列表:

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title>data tree</title>
  </head>
  <body>
    <div id="container">

    </div>
    <script type="text/javascript">
      const countries = {
        "Europe": {
          "France": {},
          "Spain": {}
        },
        "America": {
          "North": {
            "USA": {},
            "Canada": {}
          },
          "South": {
            "Brazil": {},
            "Argentina": {}
          }
        }
      };

      //Getting the container were I want to put my list
      let container = document.getElementById('container');

      function createTree(container, data) {
        //Recursive function which will create as much lists as I need
        function rec(obj) {
          let list = document.createElement('ul');
          //Looping through the object properties
          for (let item in obj){
            //If the object property is object too
            //And it has its own properties
            //Then create a list ite for it 
            //And put a new list in it with the recursion
            if (Object.keys(obj[item]).length) {
              let listItem = document.createElement('li');
              listItem.textContent += obj[item];
              list.appendChild(listItem);
              rec(obj[item]);
            }
          }
          
          return list;
        }

        //In the end add the list to the container
        container.appendChild(rec(data));
      }

      createTree(container, countries);
    </script>
  </body>
</html>

如果可以用其他方法(例如循环或其他方法)来做到这一点,那也是可以接受的。

谢谢。

1 个答案:

答案 0 :(得分:3)

无论每次迭代,您都需要为创建的li的内容分配内容-然后检查关联对象是否具有任何键,如果有,请执行递归调用:< / p>

const countries = {
  "Europe": {
    "France": {},
    "Spain": {}
  },
  "America": {
    "North": {
      "USA": {},
      "Canada": {}
    },
    "South": {
      "Brazil": {},
      "Argentina": {}
    }
  }
};

function createTree(container, data) {
  const ul = container.appendChild(document.createElement('ul'));
  for (const [key, val] of Object.entries(data)) {
    const li = ul.appendChild(document.createElement('li'));
    li.textContent = key;
    if (Object.keys(val).length) {
      createTree(li, val);
    }
  }
}

createTree(document.getElementById('container'), countries);
<div id="container">

</div>

我想如果您真的想要的话,可以改用DocumentFragment:

const countries = {
  "Europe": {
    "France": {},
    "Spain": {}
  },
  "America": {
    "North": {
      "USA": {},
      "Canada": {}
    },
    "South": {
      "Brazil": {},
      "Argentina": {}
    }
  }
};

function createTree(container, data) {
  const ul = container.appendChild(document.createElement('ul'));
  for (const [key, val] of Object.entries(data)) {
    const li = ul.appendChild(document.createElement('li'));
    li.textContent = key;
    if (Object.keys(val).length) {
      createTree(li, val);
    }
  }
}

const frag = document.createDocumentFragment();
createTree(frag, countries);
document.getElementById('container').appendChild(frag);
<div id="container">

</div>

相关问题