我希望实现的是:
- 使用一些后端逻辑生成表示目录结构的 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”中的最后一个递归调用被注释掉了,因为它进入了无限运行。任何关于为什么会发生无限执行以及如何规避它的想法,将不胜感激。
最佳答案
你唯一的错误不在递归本身,而在范围内,主要是在循环中的 i
变量上。由于您没有使用 var
或 let
定义它,它是在全局范围内定义的,因此每次迭代都会共享它的值。发生的情况是,第二次迭代将 i
的先前迭代值更改为 3,因此它总是会进入第三级 (directory1)。使用 var
或 let
,每个 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>
<
关于javascript - 使用 Javascript/jQuery/JSON 生成 HTML 来表示目录树,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54459846/