javascript - 通过嵌套的对象数组递归循环以编写嵌套列表

标签 javascript html dom

给定一个嵌套的对象数组,我试图写入一个嵌套的无序列表。

数组本身经过组织,因此每个新的子属性都会启动一个新的对象数组。该功能需要能够支持 n 级深度。

我目前的解决方案可以递归写入我现在需要的所有属性,但是在错误的

    处附加了
  • 标签。

    我认为这是因为:

      var lowUL = targetUL.querySelector('ul');
    

    我在我的递归基本案例中也使用它来附加 < li> 。 它只选择它找到的第一个

      标记,而不是在 for 循环中从该迭代中动态创建的
        标记。

        // DATA
        const org1_depts = [
          {
            name: 'accounting',
            children: [
              { name: 'accounting payable', children: [] },
              { name: 'accounting receivable', children: [] },
            ],
          },
          {
            name: 'finance',
            children: [],
          },
        ]
        
        const org2_depts = [
          {
            name: 'accounting',
            children: [
              { name: 'accounting payable', children: [] },
              {
                name: 'accounting receivable',
                children: [{ name: 'cash', children: [] }, { name: 'check', children: [] }],
              },
            ],
          },
          {
            name: 'finance',
            children: [{ name: 'investment', children: [] }],
          },
        ]
        
        // FUNCTION
        
        function listOrg(orgData,targetUL) {
          var i;
          for (i = 0; i < orgData.length; i++) {
            if (orgData[i].hasOwnProperty('name')) {
              // Take out the text from the .name property
              var nameText = document.createTextNode(orgData[i].name);
              // Define a new <li> tag
              var newLI = document.createElement('li');
              // Append text to new <li> tage - newLI
              newLI.appendChild(nameText);
              // Append element to <ul> tag
              targetUL.appendChild(newLI);
            }
        
            if (orgData[i].hasOwnProperty('children')) {
              // Define new <ul> tag
              var newUL = document.createElement('ul');
              // Append new <ul> tag
              var lowUl = targetUL.appendChild(newUL);
              // Select new lower level <ul> tag
              var lowUL = targetUL.querySelector('ul');
              // Recurse
              listOrg(orgData[i].children,lowUL);
            }
          }
        }
        
        // CALL FUNCTION
        listOrg(org1_depts,document.getElementById("org1"));
        listOrg(org2_depts,document.getElementById("org2"));
        <!DOCTYPE html>
        <html lang="en">
        <head>
          <meta charset="UTF-8">
          <meta name="viewport" content="width=device-width, initial-scale=1.0">
          <meta http-equiv="X-UA-Compatible" content="ie=edge">
          <title>Document</title>
        </head>
        <body>
        <ul id='org1'>
          Organization 1
        </ul>
        
        <ul id='org2'>
          Organization 2
        </ul>
        
        </body>
        </html>

        上面“accounting receivable”的子名称属性被放置在“accounting payable”中,这是错误的。

最佳答案

当您递归调用listOrg 函数时,您应该将newUL 变量而不是lowUL 作为参数发送。 listOrg(orgData[i].children,newUL) 这将针对新创建的 ul,您无需使用 querySelector

// DATA
const org1_depts = [
  {
    name: 'accounting',
    children: [
      { name: 'accounting payable', children: [] },
      { name: 'accounting receivable', children: [] },
    ],
  },
  {
    name: 'finance',
    children: [],
  },
]

const org2_depts = [
  {
    name: 'accounting',
    children: [
      { name: 'accounting payable', children: [] },
      {
        name: 'accounting receivable',
        children: [{ name: 'cash', children: [] }, { name: 'check', children: [] }],
      },
    ],
  },
  {
    name: 'finance',
    children: [{ name: 'investment', children: [] }],
  },
]

// FUNCTION

function listOrg(orgData,targetUL) {
  var i;
  for (i = 0; i < orgData.length; i++) {
    if (orgData[i].hasOwnProperty('name')) {
      // Take out the text from the .name property
      var nameText = document.createTextNode(orgData[i].name);
      // Define a new <li> tag
      var newLI = document.createElement('li');
      // Append text to new <li> tage - newLI
      newLI.appendChild(nameText);
      // Append element to <ul> tag
      targetUL.appendChild(newLI);
    }

    if (orgData[i].hasOwnProperty('children')) {
      // Define new <ul> tag
      var newUL = document.createElement('ul');
      // Append new <ul> tag
      var lowUl = targetUL.appendChild(newUL);
      // Select new lower level <ul> tag
      var lowUL = targetUL.querySelector('ul');
      // Recurse
      listOrg(orgData[i].children,newUL );
    }
  }
}

// CALL FUNCTION
listOrg(org1_depts,document.getElementById("org1"));
listOrg(org2_depts,document.getElementById("org2"));
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
<ul id='org1'>
  Organization 1
</ul>

<ul id='org2'>
  Organization 2
</ul>

</body>
</html>

关于javascript - 通过嵌套的对象数组递归循环以编写嵌套列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54977057/

相关文章:

javascript - 如何在不丢失链接属性的情况下将超文本链接复制到剪贴板

javascript - 使用 angular.js 选择输入复选框时如何获取表的行数据

javascript - 选择 html 表格行上的单选按钮功能

html - 为什么我的网站在移动浏览器中不显示左侧?

angular - 如何在 Angular2 应用程序中直观地突出显示/捕获不必要的 DOM 更改

javascript - 设置脚本发生错误时控制台中显示的文件名

javascript - 具有有限高度和宽度的 D3 SVG

JavaScript:我应该如何生成大量 HTML?

javascript - window.confirm 在 Chrome 中没有交互就消失

html - 未弃用的 <form target ="...">