是否可以在表单下拉列表中创建嵌套的选项字段,就像创建嵌套的 ul 列表一样?
由于更改只是美学上的,是否可以用 css 做到这一点?
原文由 stef 发布,翻译遵循 CC BY-SA 4.0 许可协议
是否可以在表单下拉列表中创建嵌套的选项字段,就像创建嵌套的 ul 列表一样?
由于更改只是美学上的,是否可以用 css 做到这一点?
原文由 stef 发布,翻译遵循 CC BY-SA 4.0 许可协议
我采用这种方法是因为找不到我正在搜索的内容。嵌套的手风琴选择。它的 CSS 非常简单,可以改进。您唯一需要的是一个包含要添加到选择中的键和值的对象。 Keys
将是子组,而键 values
(数组和单个元素)将是可选项目。
一旦你有了你的数组,你唯一需要做的就是打电话
initAccordeon(obj);
以您的数据对象作为参数,嵌套的手风琴将出现:
const obj = {
Cars: {
SwedishCars: [
"Volvo",
"Saab"
],
GermanCars: [
"Mercedes",
{
Audi: [
"Audi A3",
"Audi A4",
"Audi A5"
]
}
]
},
Food: {
Fruits: [
"Orange",
"Apple",
"Banana"
],
SaltyFoods: [
"Pretzels",
"Burger",
"Noodles"
],
Drinks: "Water"
}
};
initAccordeon(obj); // <--------------------------- Call initialization
function accordeonAddEvents() {
Array.from(document.getElementsByClassName("accordeon-header")).forEach(function(header) {
if (header.getAttribute("listener") !== "true") {
header.addEventListener("click", function() {
this.parentNode.getElementsByClassName("accordeon-body")[0].classList.toggle("hide");
});
header.setAttribute("listener", "true");
}
});
Array.from(document.getElementsByClassName("button-group")).forEach(function(but) {
if (but.getAttribute("listener") !== "true") {
but.addEventListener("click", function() {
if (this.getAttribute("depth") === "-1") {
let header = this;
while ((header = header.parentElement) && header.className !== "accordeon");
header.getElementsByClassName("accordeon-header")[0].innerHTML = this.innerHTML;
return;
}
const groups = Array.from(this.parentNode.getElementsByClassName("accordeon-group"));
groups.forEach(g => {
if (g.getAttribute("uuid") === this.getAttribute("uuid") &&
g.getAttribute("depth") === this.getAttribute("depth")) {
g.classList.toggle("hide");
}
});
});
but.setAttribute("listener", "true");
}
});
}
function initAccordeon(data) {
accordeons = Array.from(document.getElementsByClassName("accordeon-body"));
accordeons.forEach(acc => {
acc.innerHTML = "";
const route = (subObj, keyIndex = 0, parent = acc, depth = 0) => {
const keys = Object.keys(subObj);
if (typeof subObj === 'object' && !Array.isArray(subObj) && keys.length > 0) {
while (keyIndex < keys.length) {
var but = document.createElement("button");
but.className = "button-group";
but.setAttribute("uuid", keyIndex);
but.setAttribute("depth", depth);
but.innerHTML = keys[keyIndex];
var group = document.createElement("div");
group.className = "accordeon-group hide";
group.setAttribute("uuid", keyIndex);
group.setAttribute("depth", depth);
route(subObj[keys[keyIndex]], 0, group, depth + 1);
keyIndex++;
parent.append(but);
parent.append(group);
}
} else {
if (!Array.isArray(subObj)) subObj = [subObj];
subObj.forEach((e, i) => {
if (typeof e === 'object') {
route(e, 0, parent, depth);
} else {
var but = document.createElement("button");
but.className = "button-group";
but.setAttribute("uuid", i);
but.setAttribute("depth", "-1");
but.innerHTML = e;
parent.append(but);
}
});
}
};
route(data);
});
accordeonAddEvents();
}
.accordeon {
width: 460px;
height: auto;
min-height: 340px;
font-size: 20px;
cursor: pointer;
user-select: none;
-moz-user-select: none;
-khtml-user-select: none;
-webkit-user-select: none;
-o-user-select: none;
display: block;
position: relative;
z-index: 10;
}
.accordeon-header {
display: inline-block;
width: 450px;
border: solid 0.1vw black;
border-radius: 0.2vw;
background-color: white;
padding-left: 10px;
color: black;
}
.accordeon-header:hover {
opacity: 0.7;
}
.accordeon-body {
display: block;
position: absolute;
}
.button-group {
display: block;
cursor: pointer;
width: 460px;
text-align: left;
font-size: 20px;
font-weight: bold;
}
.accordeon-group {
padding-left: 20px;
}
.accordeon-group .button-group {
width: 100%;
}
.button-group[depth="-1"] {
color: green;
}
.hide {
display: none;
}
<div class="accordeon">
<span class="accordeon-header">Select something</span>
<div class="accordeon-body hide">
</div>
</div>
原文由 AlexSp3 发布,翻译遵循 CC BY-SA 4.0 许可协议
3 回答975 阅读✓ 已解决
4 回答1.3k 阅读✓ 已解决
2 回答938 阅读✓ 已解决
2 回答1.5k 阅读✓ 已解决
2 回答1.3k 阅读✓ 已解决
2 回答912 阅读✓ 已解决
2 回答1.1k 阅读✓ 已解决
您可以使用
<optgroup>
创建单层嵌套…请注意,组标签不是可选择的选项。在那种情况下,我建议使用在他的评论中链接到的问题的最佳答案中提到的文本缩进解决方案。