根据对象的关键结构生成元素

时间:2018-06-18 13:37:40

标签: javascript recursion dynamically-generated

我有一个多维对象。现在我想根据这个对象的关键结构生成DOM元素。

作为默认视图,所有根键都应显示为div元素。单击其中一个元素后,div应替换为单击键的直接子元素。

我当前的版本看起来像这样

对象:

let object = {
    "1.0": {
        "1.0.1": {},
        "1.0.2": {},
    },
    "1.1": {
        "1.1.1": {
            "1.1.1.1": {},
        },
        "1.1.2": {},
    },   
};

这是我为每个键生成DOM元素的递归函数:

function categoryTree(obj) {
    for (var key in obj) {
        categoryContainer.innerHTML += "<div>" + key + "</div>";
        categoryTree(obj[key]);
    }
}

现在,我不知道如何进行交互,只有在点击父级时才显示子键。

2 个答案:

答案 0 :(得分:1)

只需使用DOM方法:

const n = (type, settings = {}) => Object.assign(document.createElement(type), settings);

function treeNode(name, children) {
  const text = n("p", { textContent: name });

  const container = n("div");
  container.style.display = "none";
  for(const [childName, child] of Object.entries(children))
    container.appendChild(treeNode(childName, child));

  const node = n("div");
  node.appendChild(text);
  node.appendChild(container);

  node.onclick = () => container.style.display = "block";

  return node;
}

categoryContainer.appendChild(treeNode("root", object));

答案 1 :(得分:1)

您可以使用createElementfor...in循环构建嵌套的html结构。然后,您还可以在div上添加事件侦听器,以切换其子display属性。

&#13;
&#13;
let object = {
  "1.0": {
    "1.0.1": {},
    "1.0.2": {}
  },
  "1.1": {
    "1.1.1": {
      "1.1.1.1": {}
    },
    "1.1.2": {}
  }
}

let categoryContainer = document.querySelector(".categoryContainer")

function categoryTree(obj, parent, start = true) {
  for (var key in obj) {
    let div = document.createElement("div");
    div.textContent = key;
    if (parent.children) parent.className += " bold";
    if (!start) div.className = "normal hide"

    div.addEventListener('click', function(e) {
      e.stopPropagation()
      Array.from(div.children).forEach(child => {
        child.classList.toggle('hide')
      })
    })
    categoryTree(obj[key], div, false)
    parent.appendChild(div)
  }
}


categoryTree(object, categoryContainer)
&#13;
.hide {display: none;}
.normal {font-weight: normal;}
.bold {font-weight: bold;}
&#13;
<div class="categoryContainer"></div>
&#13;
&#13;
&#13;