【问题标题】:Generating HTML to represent a directory tree using Javascript/jQuery/JSON使用 Javascript/jQuery/JSON 生成 HTML 以表示目录树
【发布时间】:2019-06-24 20:53:42
【问题描述】:

我希望达到的目标如下:

  • 使用一些后端逻辑生成代表目录结构的 JSON。
  • 将此 JSON 传递给 JavaScript 函数以创建表示目录结构的 HTML。

我要生成的 HTML 如下:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title></title>
   <!-- Latest compiled and minified CSS -->
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css">

  <!-- jQuery library -->
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

  <!-- Popper JS -->
  <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.6/umd/popper.min.js"></script>

  <!-- Latest compiled JavaScript -->
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js"></script> 
</head>
<body>
  
  <h1>Contents of "Some"</h1>

  <ul>
    <li data-toggle="collapse" data-target="#first">Collapsible </li>
      <ul id="first" class="collapse">
        <li>Lorem ipsum dolor text....</li>
        <li>Lorem ipsum dolor text....</li>
        <li>Lorem ipsum dolor text....</li>
          <li data-toggle="collapse" data-target="#sub">Collapsible</li>
            <ul id="sub" class="collapse">
              <li>Lorem ipsum dolor text....</li>
              <li>Lorem ipsum dolor text....</li>
              <li>Lorem ipsum dolor text....</li>
            </ul> 
      </ul> 
    <li> File 1</li>
    <li> File 2</li>
    <li> File 3</li>
  </ul>

 
</body>
</html>

为了生成这个,我假设我的后端程序可以生成如下 JSON:

    <script>
      var tree = [
        {'name': 'file1',
         'type': 'file',
         'url': 'https://www.google.com'
        },
        {'name': 'file2',
         'type': 'file',
         'url': 'https://www.google.com'
        },
        {'name': 'file1',
         'type': 'file',
         'url': 'https://www.google.com'
        },
        {'name': 'directory1',
         'type': 'folder',
         'url': 'https://www.google.com',
         'contents': [
            {'name': 'file1',
             'type': 'file',
             'url': 'https://www.google.com'
            },
            {'name': 'file2',
             'type': 'file',
             'url': 'https://www.google.com'
            },
           ]
        },
      ]

上述情况下的 URL 将被一些自定义 URL 替换,这将使人们能够下载文件。这与手头的问题无关。

现在,为了生成最终的 HTML 代码,我一直在尝试使用 Javascript 中的递归来构造 DOM 结构。但是由于某种原因我无法弄清楚,我最终构建了一个无限的 DOM。这是我目前的尝试。

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title></title>
  <!-- Latest compiled and minified CSS -->
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css">

  <!-- jQuery library -->
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

  <!-- Popper JS -->
  <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.6/umd/popper.min.js"></script>

  <!-- Latest compiled JavaScript -->
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js"></script>
</head>

<body>
  <script>
    var tree = [{
        'name': 'file1',
        'type': 'file',
        'url': 'https://www.google.com'
      },
      {
        'name': 'file2',
        'type': 'file',
        'url': 'https://www.google.com'
      },
      {
        'name': 'file1',
        'type': 'file',
        'url': 'https://www.google.com'
      },
      {
        'name': 'directory1',
        'type': 'folder',
        'url': 'https://www.google.com',
        'contents': [{
            'name': 'file1',
            'type': 'file',
            'url': 'https://www.google.com'
          },
          {
            'name': 'file2',
            'type': 'file',
            'url': 'https://www.google.com'
          },
        ]
      },
    ]
  </script>

  <h1>Contents of "Some"</h1>


  <div id="tree_container">

  </div>

  <script>
    var listContentsOf = function(tree, container = 'tree_container', depth = '1') {
      console.log(tree);
      console.log(container);
      console.log(depth);

      $('#' + container).append('<ul id="' + depth + '"> </ul>');
      for (i = 0; i < tree.length; i++) {
        if (tree[i].type == 'file') {
          $('#' + depth).append('<li>' + tree[i].name + '</li>');
        } else if (tree[i].type == 'folder') {
          $('#' + depth).append('<li>' + tree[i].name + '</li>');
          subID = depth + i;
          $('#' + depth).append('<div id="' + subID + 'holder"> </div>');
          console.log(tree[i].contents);
          console.log(subID + 'holder');
          // listContentsOf(tree[i].contents, subID + 'holder', subID);
        }
      }
    };

    listContentsOf(tree);
  </script>

</body>
<

'if else' 中的最后一个递归调用被注释了,因为它进入了无限运行。任何关于为什么会发生无限执行以及如何规避它的想法将不胜感激。

【问题讨论】:

    标签: javascript jquery html recursion


    【解决方案1】:

    您唯一的错误不在递归本身,而是在范围内,主要是循环中的i 变量。由于您没有使用varlet 定义它,它是在全局范围内定义的,因此每次迭代都会共享它的价值。发生的情况是第二次迭代将之前的迭代值i 更改为 3,因此它总是会进入第三级(directory1)。对于varlet,每个i 都将在其自己的范围内定义,因此它的值将始终可靠。

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <title></title>
      <!-- Latest compiled and minified CSS -->
      <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css">
    
      <!-- jQuery library -->
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    
      <!-- Popper JS -->
      <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.6/umd/popper.min.js"></script>
    
      <!-- Latest compiled JavaScript -->
      <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js"></script>
    </head>
    
    <body>
      <script>
        var tree = [{
            'name': 'file1',
            'type': 'file',
            'url': 'https://www.google.com'
          },
          {
            'name': 'file2',
            'type': 'file',
            'url': 'https://www.google.com'
          },
          {
            'name': 'file1',
            'type': 'file',
            'url': 'https://www.google.com'
          },
          {
            'name': 'directory1',
            'type': 'folder',
            'url': 'https://www.google.com',
            'contents': [{
                'name': 'file1',
                'type': 'file',
                'url': 'https://www.google.com'
              },
              {
                'name': 'file2',
                'type': 'file',
                'url': 'https://www.google.com'
              },
            ]
          },
        ]
      </script>
    
      <h1>Contents of "Some"</h1>
    
    
      <div id="tree_container">
    
      </div>
    
      <script>
        var listContentsOf = function(tree, container = 'tree_container', depth = '1') {
          console.log(tree);
          console.log(container);
          console.log(depth);
    
          $('#' + container).append('<ul id="' + depth + '"> </ul>');
          for (var i = 0; i < tree.length; i++) {
            if (tree[i].type == 'file') {
              $('#' + depth).append('<li>' + tree[i].name + '</li>');
            } else if (tree[i].type == 'folder') {
              $('#' + depth).append('<li>' + tree[i].name + '</li>');
              subID = depth + i;
              $('#' + depth).append('<div id="' + subID + 'holder"> </div>');
              console.log(tree[i].contents);
              console.log(subID + 'holder');
              listContentsOf(tree[i].contents, subID + 'holder', subID);
            }
          }
        };
    
        listContentsOf(tree);
      </script>
    
    </body>
    <

    【讨论】:

    • 非常感谢!他们说作用域和每种语言处理它们的方式的差异有一种困扰程序员的方式。这正好证明了!我必须承认阅读了 i=0var i=0 之间的区别,但由于 JS 不是我的“通用语”,我根本没有考虑过这一点。再次感谢。
    猜你喜欢
    • 2017-04-28
    • 2014-10-03
    • 1970-01-01
    • 2012-06-13
    • 2015-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多