我基于对象结构生成嵌套的div元素。单击父级,可以切换子级。
现在,我想生成单击序列和“选定”元素的路径,并用斜杠分隔。当用户单击读取->新闻->运动时,字符串路径应为“读取/新闻/体育”。现在,当用户点击“已读->图书”时,路径应为“已读/图书”
这是我当前的版本:https://codepen.io/iamrbn/pen/yEqPjG
let path = "";
let object = {
"design": {
"inspiration": {},
"news": {}
},
"read": {
"news": {
"sport": {}
},
"books": {}
},
"code": {}
}
let categoryContainer = document.querySelector(".categoryContainer")
function categoryTree(obj, parent, start = true) {
for (var key in obj) {
let div = document.createElement("div");
div.textContent = key;
div.classList.add("category");
if (parent.children) parent.className += " bold";
if (!start) div.className = "normal hide category";
div.addEventListener('click', function(e) {
e.stopPropagation()
this.classList.toggle('active');
Array.from(div.children).forEach(child => {
child.classList.toggle('hide');
})
})
categoryTree(obj[key], div, false)
parent.appendChild(div)
}
}
categoryTree(object, categoryContainer)
.category {
color: black;
display: block;
line-height: 40px;
background-color: RGBA(83, 86, 90, 0.2);
margin: 8px;
}
.category .category {
display: inline-block;
margin: 0 8px;
padding: 0 8px;
}
.category.hide {display: none;}
.category.normal {font-weight: normal;}
.category.bold {font-weight: bold;}
.category.active {color: red;}
<div class="categoryContainer"></div>
答案 0 :(得分:1)
这是一种方法。除了添加对新getParents()
函数的调用之外,您现有的代码均未修改,该函数通过递归爬网DOM树以生成指向所单击节点的“路径”来进行工作:
let path = "";
let object = {
"design": {
"inspiration": {},
"news": {}
},
"read": {
"news": {
"sport": {}
},
"books": {}
},
"code": {}
}
let categoryContainer = document.querySelector(".categoryContainer")
function categoryTree(obj, parent, start = true) {
for (var key in obj) {
let div = document.createElement("div");
div.textContent = key;
div.classList.add("category");
if (parent.children) parent.className += " bold";
if (!start) div.className = "normal hide category";
div.addEventListener('click', function(e) {
e.stopPropagation()
this.classList.toggle('active');
Array.from(div.children).forEach(child => {
child.classList.toggle('hide');
})
var thePath = getParents(e.target); // <--- new
console.log(thePath)
})
categoryTree(obj[key], div, false)
parent.appendChild(div)
}
}
function getParents(node, path) {
// Cheat a bit here: we know the textnode we want is the first child node, so we don't have to iterate through all children and check their nodeType:
let thisName = node.childNodes[0].textContent;
path = path ? (thisName + "/" + path) : thisName ;
// iterate to parent unless we're at the container:
if (node.parentNode.className.split(/\s+/).indexOf("categoryContainer") !== -1) {
return path;
} else {
return getParents(node.parentNode, path);
}
}
categoryTree(object, categoryContainer)
.category {
color: black;
display: block;
line-height: 40px;
background-color: RGBA(83, 86, 90, 0.2);
margin: 8px;
}
.category .category {
display: inline-block;
margin: 0 8px;
padding: 0 8px;
}
.category.hide {
display: none;
}
.category.normal {
font-weight: normal;
}
.category.bold {
font-weight: bold;
}
.category.active {
color: red;
}
<div class="categoryContainer"></div>