如何使用JavaScript从路径对象构建嵌套的UL结构?
例如,给定以下路径数组:
var paths = [
"d1/d2/d3/file1.txt",
"d1/d2/d3/file2.txt",
];
我想建立以下UL
<ul class="base-UL">
<li class="folder">d1
<ul>
<li class="folder">d2
<ul>
<li class="folder">d3
<ul>
<li class="file" data-url="d1/d2/d3/file1.text">file1.text</li>
<li class="file" data-url="d1/d2/d3/file2.text">file2.text</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
我应该如何构建一个这样做的递归函数?
修改 我能够成功编写一个执行此操作的函数,但我无法弄清楚如何将完整路径作为文件元素中的数据属性: 见下文:
function buildFromPathList(paths) {
for (var i = 0, path; path = paths[i]; ++i) {
var pathParts = path.split("/");
var subObj = tree_;
for (var j = 0, folderName; folderName = pathParts[j]; ++j) {
if (!subObj[folderName]) {
subObj[folderName] = j < pathParts.length - 1 ? {} : null;
}
subObj = subObj[folderName];
}
}
return tree_;
}
function render(object) {
for (var folder in object) {
if (!object[folder]) {
var name = folder.trim();
html_ += '<li class="file>' + folder + '</li>';
} else {
html_ += '<li class="folder">' + folder + '<ul>';
render(object[folder]);
html_ += "</ul>";
}
}
}
var html_ = [];
render(buildFromPathList(paths));
答案 0 :(得分:11)
var paths = [
"d1/d2/d3/file1.txt",
"d1/d2/d3/file2.txt",
];
我首先建立一个更好的数据结构:
var hierarchy = paths.reduce(function(hier,path){
var x = hier;
path.split('/').forEach(function(item){
if(!x[item]){
x[item] = {};
}
x = x[item];
});
x.path = path;
return hier;
}, {});
然后使用它来构建HTML(没有缩进):
var makeul = function(hierarchy, classname){
var dirs = Object.keys(hierarchy);
var ul = '<ul';
if(classname){
ul += ' class="' + classname + '"';
}
ul += '>\n';
dirs.forEach(function(dir){
var path = hierarchy[dir].path;
if(path){ // file
ul += '<li class="file" data-url="' + path + '">' + dir + '</li>\n';
}else{
ul += '<li class="folder">' + dir + '\n';
ul += makeul(hierarchy[dir]);
ul += '</li>\n';
}
});
ul += '</ul>\n';
return ul;
};
makeul(hierarchy, 'base-UL');
答案 1 :(得分:4)
我将从一个示例开始,看看您是否可以自己弄清楚HTML生成。
你也可以在Github上找到这个:https://github.com/vasilionjea/treepath
路径:
var paths = [
"d1/d2/d3/file1.txt",
"d1/d2/d3/file2.txt",
"d2/d3/file3.txt",
"d3/file4.txt",
"d1/d2/first.png",
"d2/second.png",
"d1/photo1.jpg",
"d1/photo2.jpg",
"animate.gif"
];
构建树的代码:
var tree = {
// Represents the "root" directory, like in a filesystem.
root: {
absolute_path: '',
files: []
}
};
function buildTree(parts) {
var lastDir = 'root';
var abs_path = '';
parts.forEach(function(name) {
// It's a directory
if (name.indexOf('.') === -1) {
lastDir = name;
abs_path += lastDir + '/';
if (!tree[name]) {
tree[name] = {
absolute_path: abs_path,
files: []
};
}
} else {
tree[lastDir].files.push(name);
}
});
}
paths.forEach(function(path, index, array) {
buildTree(path.split('/'));
});
现在记录构建的树:
console.log(tree);
// Output:
{
"root": {
"absolute_path": "",
"files": [
"animate.gif"
]
},
"d1": {
"absolute_path": "d1/",
"files": [
"photo1.jpg",
"photo2.jpg"
]
},
"d2": {
"absolute_path": "d1/d2/",
"files": [
"first.png",
"second.png"
]
},
"d3": {
"absolute_path": "d1/d2/d3/",
"files": [
"file1.txt",
"file2.txt",
"file3.txt",
"file4.txt"
]
}
}