效果如图
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body style="height:100%;width:100%;">
<ul id="tree" class="tree"></ul>
<script>
var opensvg = '<span class="svg"><svg viewBox="64 64 896 896" data-icon="plus-square" width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><path d="M328 544h152v152c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8V544h152c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8H544V328c0-4.4-3.6-8-8-8h-48c-4.4 0-8 3.6-8 8v152H328c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8z"></path><path d="M880 112H144c-17.7 0-32 14.3-32 32v736c0 17.7 14.3 32 32 32h736c17.7 0 32-14.3 32-32V144c0-17.7-14.3-32-32-32zm-40 728H184V184h656v656z"></path></svg></span>'
var closesvg = '<span class="svg"><svg viewBox="64 64 896 896" data-icon="minus-square" width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><path d="M328 544h368c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8H328c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8z"></path><path d="M880 112H144c-17.7 0-32 14.3-32 32v736c0 17.7 14.3 32 32 32h736c17.7 0 32-14.3 32-32V144c0-17.7-14.3-32-32-32zm-40 728H184V184h656v656z"></path></svg></span>'
var filesvg = '<svg viewBox="64 64 896 896" data-icon="file" width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><path d="M854.6 288.6L639.4 73.4c-6-6-14.1-9.4-22.6-9.4H192c-17.7 0-32 14.3-32 32v832c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V311.3c0-8.5-3.4-16.7-9.4-22.7zM790.2 326H602V137.8L790.2 326zm1.8 562H232V136h302v216a42 42 0 0 0 42 42h216v494z"></path></svg>'
// 递归函数生成树的节点
function createNode(data) {
var li = document.createElement("li");
var div = document.createElement("div");
div.classList.add("nodetree");
if (data.children) {
div.innerHTML = opensvg + '<span>' + data.name + '</span>';
} else {
div.innerHTML = filesvg + '<span>' + data.name + '</span>';
}
li.appendChild(div);
if (data.children) {
var ul = document.createElement("ul");
for (var i = 0; i < data.children.length; i++) {
ul.appendChild(createNode(data.children[i]));
}
li.appendChild(ul);
}
return li;
}
// 生成树的节点并添加到树的容器中
var treeData = [
{
name:'测试1',
children:[
{
name:'测试1-1'
}
]
},
{
name:'测试2',
children:[
{
name:'测试2-1'
}
]
}
]
var tree = document.getElementById("tree");
for (var i = 0; i < treeData.length; i++) {
tree.appendChild(createNode(treeData[i]));
}
// 定义节点的样式和事件
var nodes = document.querySelectorAll("#tree li");
for (var i = 0; i < nodes.length; i++) {
nodes[i].classList.add("node");
nodes[i].addEventListener("click", function (e) {
if (this.getAttribute('class').indexOf('open') > -1) {
this.querySelector(".nodetree .svg").innerHTML = opensvg;
} else {
this.querySelector(".nodetree .svg").innerHTML = closesvg;
}
e.stopPropagation();
this.classList.toggle("open");
});
}
</script>
</body>
<style>
.tree {
display: inline-block;
height: 24px;
margin: 0;
padding: 0 5px;
color: rgba(0, 0, 0, .65);
line-height: 24px;
text-decoration: none;
vertical-align: top;
border-radius: 2px;
cursor: pointer;
transition: all .3s;
font-size: 14px;
font-variant: tabular-nums;
font-feature-settings: "tnum";
}
.node {
cursor: pointer;
}
.nodetree {
display: flex;
align-items: center;
}
.nodetree svg {
margin-right: 5px;
vertical-align: middle;
}
.node>ul {
display: none;
}
.node.open>ul {
display: block;
margin: 0;
padding: 0 0 0 18px;
}
ul>li {
position: relative;
margin: 0;
padding: 4px 0;
white-space: nowrap;
list-style: none;
outline: 0;
}
ul li:not(:last-child):before {
position: absolute;
left: 7px;
width: 1px;
height: 100%;
height: calc(100% - 22px);
margin: 22px 0 0;
border-left: 1px solid #d9d9d9;
content: " ";
}
</style>
</html>