函数中的递归创建 DOM 树

Recursion in function creating DOM tree

本文关键字:DOM 创建 递归 函数      更新时间:2023-09-26

好人,请向我解释一下,请使用此功能:

function createTreeDom(obj) {
  if (isObjectEmpty(obj)) return;
  var ul = document.createElement('ul');
  for (var key in obj) {
    var li = document.createElement('li');
    li.innerHTML = key;
    var childrenUl = createTreeDom(obj[key]);
    if (childrenUl) li.appendChild(childrenUl);
    ul.appendChild(li);
  }
  return ul;
}

这是沙盒的链接,它是完整的代码:http://jsbin.com/zonoxereqa/1/edit

我如何看待这些功能很好理解:

function isObjectEmpty(obj) {
  for (var key in obj) {
    return false;
  }
  return true;
}
function createTree(container, obj) {
  container.appendChild( createTreeDom(obj) );
}

只有递归函数createTreeDom(obj)我不太了解她的工作,请帮我解释一下她的工作。

我仍然不明白分配给变量 childrenUl 的内容是什么?为什么它总是在调试器中未定义?

它使用嵌套对象创建嵌套列表。在一个级别的嵌套中,它创建一个单级简单ul li, li ...列表。但是如果某个值是这样的非空对象

var arg = { "one":{}, "two":{}, "three":{"subone":{}, "subtwo":{}}, "four":{}};

然后将子对象作为子列表追加到递归中

var childrenUl = createTreeDom(obj[key]);
if (childrenUl) li.appendChild(childrenUl);

如果值不是空对象,则不会创建子列表,因为第一个命令有一个停止条件:

if (isObjectEmpty(obj)) return;

上面的数组逐步进行:对于第一项,该函数创建ul元素并将li添加到其中,key="one"obj[key]={}

<ul>
  <li>one</li>
</ul>

但是还没有完成,现在递归被称为:createTreeDom({})。由于isObjectEmpty({})(显然)返回 true,因此递归结束,childrenUl未定义。因此,没有向li添加任何内容,循环跳转到第二个节点,这也只是一个简单的字符串文字,因此它添加了另一个li节点:

<ul>
  <li>one</li>
  <li>two</li>
</ul>

现在的重点是:第三个论点。在执行转到递归之前,它看起来像这样:

<ul>
  <li>one</li>
  <li>two</li>
  <li>three</li>
</ul>

但是第三个成员的值不是空对象,所以命令

if (childrenUl) li.appendChild(childrenUl);

创建一个ul节点,如上所示逐步填充其内容,并将其附加到 li 元素:

<ul>
  <li>one</li>
  <li>two</li>
  <li>three
    <ul>
      <li>subone</li>
      <li>subtwo</li>
    </ul>
  </li>
</ul>

如果某些嵌套项包含另一个非空对象,则会将其作为子列表附加到某个子列表li依此类推。

阅读等效物可能会更好:

function createTreeDom(obj) {
  var ul = document.createElement('ul');
  for (var key in obj) {
    var li = document.createElement('li');
    li.innerHTML = key;
    if (!isObjectEmpty(obj[key])) {
      var childrenUl = createTreeDom(obj[key]);
      li.appendChild(childrenUl);
    }
    ul.appendChild(li);
  }
  return ul;
}