在交互式 flowchart/tree 图表中隐藏未选择的选项
Hiding unselected options in an interactive flowchart/tree diagram
我正在寻求一些 Javascript 代码的帮助,我正试图从另一个网站改编这些代码,但我无法让它执行我想要它执行的操作。
我想在 HTML 代码中完全使用 CSS 和 javascript 来完成此操作。我是一个完整的 javascript 初学者。
在下面的 HTML 代码中,您可以单击一个复选框,它会显示下一级选项。
但是,我希望发生的事情是,例如,选择 'Option 1',然后隐藏 'Option 2' 和 'Option 3'。目前,它们保留在视图中,可以点击。
,然后选择选项1.2,然后隐藏'Option 1.1'的其他两个选项。
本质上,我希望用户能够向下导航一棵树,但一次只能导航一个分支,并且在他们做出选择后,同一级别中未选择的选项消失。
当然,反之亦然,如果他们在更高级别清除了一个选项,那么整个菜单就会在该级别重新显示。
我尝试了多种不同的编码,但它们要么隐藏所有内容,要么使所有复选框都没有响应!此处显示我缺乏 javascript 语法知识,但我认为解决方案包括将同一级别中未勾选的框转到 'hide' 的 class,同时保留已勾选的框勾选并显示 class of 'active'
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
ul,
#myUL {
list-style-type: none;
}
#myUL {
margin: 0;
padding: 0;
}
.box {
cursor: pointer;
-webkit-user-select: none;
/* Safari 3.1+ */
-moz-user-select: none;
/* Firefox 2+ */
-ms-user-select: none;
/* IE 10+ */
user-select: none;
}
.box::before {
content: "10";
color: black;
display: inline-block;
margin-right: 6px;
}
.check-box::before {
content: "11";
color: dodgerblue;
}
.nested {
display: none;
}
.active {
display: block;
}
.hide {
display: none;
}
</style>
</head>
<body>
<h2>Interactive Decision Tree</h2>
<ul id="myUL">
<li><span class="box">Option 1</span>
<ul class="nested">
<li><span class="box">Option 1.1</span>
<ul class="nested">
<li><span class="box">Option 1.1.1</span></li>
<li><span class="box">Option 1.1.2</span></li>
<li><span class="box">Option 1.1.3</span></li>
</ul>
</li>
<li><span class="box">Option 1.2</span>
<ul class="nested">
<li><span class="box">Option 1.2.1</span></li>
<li><span class="box">Option 1.2.2</span></li>
<li><span class="box">Option 1.2.3</span></li>
</ul>
</li>
<li><span class="box">Option 1.3</span>
<ul class="nested">
<li><span class="box">Option 1.3.1</span></li>
<li><span class="box">Option 1.3.2</span></li>
<li><span class="box">Option 1.3.3</span></li>
</ul>
</li>
</ul>
<li><span class="box">Option 2</span>
<ul class="nested">
<li><span class="box">Option 2.1</span>
<ul class="nested">
<li><span class="box">Option 2.1.1</span></li>
<li><span class="box">Option 2.1.2</span></li>
<li><span class="box">Option 2.1.3</span></li>
</ul>
</li>
<li><span class="box">Option 2.2</span>
<ul class="nested">
<li><span class="box">Option 2.2.1</span></li>
<li><span class="box">Option 2.2.2</span></li>
<li><span class="box">Option 2.2.3</span></li>
</ul>
</li>
<li><span class="box">Option 2.3</span>
<ul class="nested">
<li><span class="box">Option 2.3.1</span></li>
<li><span class="box">Option 2.3.2</span></li>
<li><span class="box">Option 2.3.3</span></li>
</ul>
</li>
</ul>
<li><span class="box">Option 3</span>
<ul class="nested">
<li><span class="box">Option 3.1</span>
<ul class="nested">
<li><span class="box">Option 3.1.1</span></li>
<li><span class="box">Option 3.1.2</span></li>
<li><span class="box">Option 3.1.3</span></li>
</ul>
</li>
<li><span class="box">Option 3.2</span>
<ul class="nested">
<li><span class="box">Option 3.2.1</span></li>
<li><span class="box">Option 3.2.2</span></li>
<li><span class="box">Option 3.2.3</span></li>
</ul>
</li>
<li><span class="box">Option 3.3</span>
<ul class="nested">
<li><span class="box">Option 3.3.1</span></li>
<li><span class="box">Option 3.3.2</span></li>
<li><span class="box">Option 3.3.3</span></li>
</ul>
</li>
</ul>
</li>
</ul>
<script>
var toggler = document.getElementsByClassName("box");
var i;
for (i = 0; i < toggler.length; i++) {
toggler[i].addEventListener("click", function() {
this.parentElement.querySelector(".nested").classList.toggle("active");
this.classList.toggle("check-box");
});
}
</script>
</body>
</html>
感谢您提供使其按预期工作所需的补充。
因此,我针对自己的问题编写了一个解决方案。我意识到我发布的示例的功能不足以勾选复选框并显示项目,无论您是在选择列表中向上还是向下。因此,它需要一种不同的方法,如下所示。这对我有用,而且我在编写所有代码时完全理解它,并改编了来自各种其他来源的代码。希望这对以后的其他人有所帮助。
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
ul,
#myUL {
list-style-type: none;
}
#myUL {
margin: 0;
padding: 0;
}
.box hide {
cursor: pointer;
-webkit-user-select: none;
/* Safari 3.1+ */
-moz-user-select: none;
/* Firefox 2+ */
-ms-user-select: none;
/* IE 10+ */
user-select: none;
}
.box::before {
content: "10";
color: black;
display: inline-block;
margin-right: 6px;
}
.check-box::before {
content: "11";
color: dodgerblue;
}
.hide {
display: none;
}
.show {
display: block;
}
</style>
</head>
<body>
<h2>Interactive Decision Tree</h2>
<p id="O" class="box">Start</p>
<p id="O1" class="box hide">Option O1</p>
<p id="O11" class="box hide">Option O11</p>
<p id="O111" class="box hide">Option O111</p>
<p id="O112" class="box hide">Option O112</p>
<p id="O113" class="box hide">Option O113</p>
<p id="O12" class="box hide">Option O12</p>
<p id="O121" class="box hide">Option O121</p>
<p id="O122" class="box hide">Option O122</p>
<p id="O123" class="box hide">Option O123</p>
<p id="O13" class="box hide">Option O13</p>
<p id="O131" class="box hide">Option O131</p>
<p id="O132" class="box hide">Option O132</p>
<p id="O133" class="box hide">Option O133</p>
<p id="O2" class="box hide">Option O2</p>
<p id="O21" class="box hide">Option O21</p>
<p id="O211" class="box hide">Option O211</p>
<p id="O212" class="box hide">Option O212</p>
<p id="O213" class="box hide">Option O213</p>
<p id="O22" class="box hide">Option O22</p>
<p id="O221" class="box hide">Option O221</p>
<p id="O222" class="box hide">Option O222</p>
<p id="O223" class="box hide">Option O223</p>
<p id="O23" class="box hide">Option O23</p>
<p id="O231" class="box hide">Option O231</p>
<p id="O232" class="box hide">Option O232</p>
<p id="O233" class="box hide">Option O233</p>
<p id="O3" class="box hide">Option O3</p>
<p id="O31" class="box hide">Option O31</p>
<p id="O311" class="box hide">Option O311</p>
<p id="O312" class="box hide">Option O312</p>
<p id="O313" class="box hide">Option O313</p>
<p id="O32" class="box hide">Option O32</p>
<p id="O321" class="box hide">Option O321</p>
<p id="O322" class="box hide">Option O322</p>
<p id="O323" class="box hide">Option O323</p>
<p id="O33" class="box hide">Option O33</p>
<p id="O331" class="box hide">Option O331</p>
<p id="O332" class="box hide">Option O332</p>
<p id="O333" class="box hide">Option O333</p>
<script>
function getElementsStartWithId(id) {
var children = document.body.getElementsByTagName('*');
var elements = [],
child;
for (var i = 0, length = children.length; i < length; i++) {
child = children[i];
if (child.id.substr(0, id.length) == id)
elements.push(child);
};
return elements;
}
function getNextLayerDown(id) {
var children = document.body.getElementsByTagName('*');
var elements = [],
child;
for (var i = 0, length = children.length; i < length; i++) {
child = children[i];
if (child.id.substring(0, child.id.length - 1) == id)
elements.push(child);
};
return elements;
}
function getAllPreviousLayers(id) {
var children = document.body.getElementsByTagName('*');
var elements = [],
child;
var newId = id
do {
for (var i = 0, length = children.length; i < length; i++) {
child = children[i];
if (child.id == newId)
elements.push(child);
};
var newId = newId.substring(0, newId.length - 1);
}
while (newId.length > 0);
return elements;
}
function updateShowItems(itemId) {
// hide all previous shown items
for (i = 0; i < showItems.length; i++) {
showItems[i].classList.remove("show");
showItems[i].classList.remove("check-box");
};
var checkedItems = getAllPreviousLayers(itemId)
// add check-box to all layers picked already
for (i = 0; i < checkedItems.length; i++) {
checkedItems[i].classList.add("check-box");
};
// update show items list with latest click
showItems = getAllPreviousLayers(itemId).concat(getNextLayerDown(itemId));
// show all items now required
for (i = 0; i < showItems.length; i++) {
showItems[i].classList.add("show");
};
}
// set each ID to be a trigger point
var allItems = getElementsStartWithId("O");
var showItems = getNextLayerDown("O");
console.log(showItems);
var i;
for (i = 0; i < allItems.length; i++) {
allItems[i].addEventListener("click", function() {
updateShowItems(this.id);
});
};
</script>
</body>
</html>
我正在寻求一些 Javascript 代码的帮助,我正试图从另一个网站改编这些代码,但我无法让它执行我想要它执行的操作。
我想在 HTML 代码中完全使用 CSS 和 javascript 来完成此操作。我是一个完整的 javascript 初学者。
在下面的 HTML 代码中,您可以单击一个复选框,它会显示下一级选项。
但是,我希望发生的事情是,例如,选择 'Option 1',然后隐藏 'Option 2' 和 'Option 3'。目前,它们保留在视图中,可以点击。
,然后选择选项1.2,然后隐藏'Option 1.1'的其他两个选项。
本质上,我希望用户能够向下导航一棵树,但一次只能导航一个分支,并且在他们做出选择后,同一级别中未选择的选项消失。
当然,反之亦然,如果他们在更高级别清除了一个选项,那么整个菜单就会在该级别重新显示。
我尝试了多种不同的编码,但它们要么隐藏所有内容,要么使所有复选框都没有响应!此处显示我缺乏 javascript 语法知识,但我认为解决方案包括将同一级别中未勾选的框转到 'hide' 的 class,同时保留已勾选的框勾选并显示 class of 'active'
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
ul,
#myUL {
list-style-type: none;
}
#myUL {
margin: 0;
padding: 0;
}
.box {
cursor: pointer;
-webkit-user-select: none;
/* Safari 3.1+ */
-moz-user-select: none;
/* Firefox 2+ */
-ms-user-select: none;
/* IE 10+ */
user-select: none;
}
.box::before {
content: "10";
color: black;
display: inline-block;
margin-right: 6px;
}
.check-box::before {
content: "11";
color: dodgerblue;
}
.nested {
display: none;
}
.active {
display: block;
}
.hide {
display: none;
}
</style>
</head>
<body>
<h2>Interactive Decision Tree</h2>
<ul id="myUL">
<li><span class="box">Option 1</span>
<ul class="nested">
<li><span class="box">Option 1.1</span>
<ul class="nested">
<li><span class="box">Option 1.1.1</span></li>
<li><span class="box">Option 1.1.2</span></li>
<li><span class="box">Option 1.1.3</span></li>
</ul>
</li>
<li><span class="box">Option 1.2</span>
<ul class="nested">
<li><span class="box">Option 1.2.1</span></li>
<li><span class="box">Option 1.2.2</span></li>
<li><span class="box">Option 1.2.3</span></li>
</ul>
</li>
<li><span class="box">Option 1.3</span>
<ul class="nested">
<li><span class="box">Option 1.3.1</span></li>
<li><span class="box">Option 1.3.2</span></li>
<li><span class="box">Option 1.3.3</span></li>
</ul>
</li>
</ul>
<li><span class="box">Option 2</span>
<ul class="nested">
<li><span class="box">Option 2.1</span>
<ul class="nested">
<li><span class="box">Option 2.1.1</span></li>
<li><span class="box">Option 2.1.2</span></li>
<li><span class="box">Option 2.1.3</span></li>
</ul>
</li>
<li><span class="box">Option 2.2</span>
<ul class="nested">
<li><span class="box">Option 2.2.1</span></li>
<li><span class="box">Option 2.2.2</span></li>
<li><span class="box">Option 2.2.3</span></li>
</ul>
</li>
<li><span class="box">Option 2.3</span>
<ul class="nested">
<li><span class="box">Option 2.3.1</span></li>
<li><span class="box">Option 2.3.2</span></li>
<li><span class="box">Option 2.3.3</span></li>
</ul>
</li>
</ul>
<li><span class="box">Option 3</span>
<ul class="nested">
<li><span class="box">Option 3.1</span>
<ul class="nested">
<li><span class="box">Option 3.1.1</span></li>
<li><span class="box">Option 3.1.2</span></li>
<li><span class="box">Option 3.1.3</span></li>
</ul>
</li>
<li><span class="box">Option 3.2</span>
<ul class="nested">
<li><span class="box">Option 3.2.1</span></li>
<li><span class="box">Option 3.2.2</span></li>
<li><span class="box">Option 3.2.3</span></li>
</ul>
</li>
<li><span class="box">Option 3.3</span>
<ul class="nested">
<li><span class="box">Option 3.3.1</span></li>
<li><span class="box">Option 3.3.2</span></li>
<li><span class="box">Option 3.3.3</span></li>
</ul>
</li>
</ul>
</li>
</ul>
<script>
var toggler = document.getElementsByClassName("box");
var i;
for (i = 0; i < toggler.length; i++) {
toggler[i].addEventListener("click", function() {
this.parentElement.querySelector(".nested").classList.toggle("active");
this.classList.toggle("check-box");
});
}
</script>
</body>
</html>
感谢您提供使其按预期工作所需的补充。
因此,我针对自己的问题编写了一个解决方案。我意识到我发布的示例的功能不足以勾选复选框并显示项目,无论您是在选择列表中向上还是向下。因此,它需要一种不同的方法,如下所示。这对我有用,而且我在编写所有代码时完全理解它,并改编了来自各种其他来源的代码。希望这对以后的其他人有所帮助。
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
ul,
#myUL {
list-style-type: none;
}
#myUL {
margin: 0;
padding: 0;
}
.box hide {
cursor: pointer;
-webkit-user-select: none;
/* Safari 3.1+ */
-moz-user-select: none;
/* Firefox 2+ */
-ms-user-select: none;
/* IE 10+ */
user-select: none;
}
.box::before {
content: "10";
color: black;
display: inline-block;
margin-right: 6px;
}
.check-box::before {
content: "11";
color: dodgerblue;
}
.hide {
display: none;
}
.show {
display: block;
}
</style>
</head>
<body>
<h2>Interactive Decision Tree</h2>
<p id="O" class="box">Start</p>
<p id="O1" class="box hide">Option O1</p>
<p id="O11" class="box hide">Option O11</p>
<p id="O111" class="box hide">Option O111</p>
<p id="O112" class="box hide">Option O112</p>
<p id="O113" class="box hide">Option O113</p>
<p id="O12" class="box hide">Option O12</p>
<p id="O121" class="box hide">Option O121</p>
<p id="O122" class="box hide">Option O122</p>
<p id="O123" class="box hide">Option O123</p>
<p id="O13" class="box hide">Option O13</p>
<p id="O131" class="box hide">Option O131</p>
<p id="O132" class="box hide">Option O132</p>
<p id="O133" class="box hide">Option O133</p>
<p id="O2" class="box hide">Option O2</p>
<p id="O21" class="box hide">Option O21</p>
<p id="O211" class="box hide">Option O211</p>
<p id="O212" class="box hide">Option O212</p>
<p id="O213" class="box hide">Option O213</p>
<p id="O22" class="box hide">Option O22</p>
<p id="O221" class="box hide">Option O221</p>
<p id="O222" class="box hide">Option O222</p>
<p id="O223" class="box hide">Option O223</p>
<p id="O23" class="box hide">Option O23</p>
<p id="O231" class="box hide">Option O231</p>
<p id="O232" class="box hide">Option O232</p>
<p id="O233" class="box hide">Option O233</p>
<p id="O3" class="box hide">Option O3</p>
<p id="O31" class="box hide">Option O31</p>
<p id="O311" class="box hide">Option O311</p>
<p id="O312" class="box hide">Option O312</p>
<p id="O313" class="box hide">Option O313</p>
<p id="O32" class="box hide">Option O32</p>
<p id="O321" class="box hide">Option O321</p>
<p id="O322" class="box hide">Option O322</p>
<p id="O323" class="box hide">Option O323</p>
<p id="O33" class="box hide">Option O33</p>
<p id="O331" class="box hide">Option O331</p>
<p id="O332" class="box hide">Option O332</p>
<p id="O333" class="box hide">Option O333</p>
<script>
function getElementsStartWithId(id) {
var children = document.body.getElementsByTagName('*');
var elements = [],
child;
for (var i = 0, length = children.length; i < length; i++) {
child = children[i];
if (child.id.substr(0, id.length) == id)
elements.push(child);
};
return elements;
}
function getNextLayerDown(id) {
var children = document.body.getElementsByTagName('*');
var elements = [],
child;
for (var i = 0, length = children.length; i < length; i++) {
child = children[i];
if (child.id.substring(0, child.id.length - 1) == id)
elements.push(child);
};
return elements;
}
function getAllPreviousLayers(id) {
var children = document.body.getElementsByTagName('*');
var elements = [],
child;
var newId = id
do {
for (var i = 0, length = children.length; i < length; i++) {
child = children[i];
if (child.id == newId)
elements.push(child);
};
var newId = newId.substring(0, newId.length - 1);
}
while (newId.length > 0);
return elements;
}
function updateShowItems(itemId) {
// hide all previous shown items
for (i = 0; i < showItems.length; i++) {
showItems[i].classList.remove("show");
showItems[i].classList.remove("check-box");
};
var checkedItems = getAllPreviousLayers(itemId)
// add check-box to all layers picked already
for (i = 0; i < checkedItems.length; i++) {
checkedItems[i].classList.add("check-box");
};
// update show items list with latest click
showItems = getAllPreviousLayers(itemId).concat(getNextLayerDown(itemId));
// show all items now required
for (i = 0; i < showItems.length; i++) {
showItems[i].classList.add("show");
};
}
// set each ID to be a trigger point
var allItems = getElementsStartWithId("O");
var showItems = getNextLayerDown("O");
console.log(showItems);
var i;
for (i = 0; i < allItems.length; i++) {
allItems[i].addEventListener("click", function() {
updateShowItems(this.id);
});
};
</script>
</body>
</html>