从点击序列中生成字符串路径
generate string path out of a click sequence
我根据对象结构生成嵌套的 div 元素。通过单击父项,您可以切换子项。
现在我想生成一个路径,用斜杠分隔,点击序列和 "selected" 元素。当用户单击阅读 -> 新闻 -> 体育时,字符串路径应为 "read/news/sport"。当用户现在点击阅读 -> 书籍时,路径现在应该是 "read/books"
这是我当前的版本: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>
这是一种方法。除了添加对新 getParents()
函数的调用外,您现有的代码未被修改,该函数通过递归地向上爬行 DOM 树来为单击的节点生成 "path":
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>
我根据对象结构生成嵌套的 div 元素。通过单击父项,您可以切换子项。
现在我想生成一个路径,用斜杠分隔,点击序列和 "selected" 元素。当用户单击阅读 -> 新闻 -> 体育时,字符串路径应为 "read/news/sport"。当用户现在点击阅读 -> 书籍时,路径现在应该是 "read/books"
这是我当前的版本: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>
这是一种方法。除了添加对新 getParents()
函数的调用外,您现有的代码未被修改,该函数通过递归地向上爬行 DOM 树来为单击的节点生成 "path":
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>