如何使用普通 JavaScript 在下拉列表中构建可折叠选项
How to build a collapsible options inside a dropdown with plain JavaScript
我正在尝试构建一个具有可折叠选项的自定义下拉菜单。
下拉菜单中的每个选项都会有子选项,选择后会给我值。
在摘要上,下拉菜单应如下所示:
考虑到以上想法,我已经通过 fiddle.
尝试了我的方法
function myFunction() {
var x = document.getElementById("myDIV");
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
}
.main-div {
display: inline-block;
padding: 15px;
width: 180px;
cursor:pointer;
border: 1px solid salmon;
}
.inner-div {
position: absolute;
width: 210px;
top: 58px;
left: 8px;
height: 300px;
border: 1px solid salmon;
}
.inner-div > ul {
list-style-type: none;
border-bottom: 1px solid salmon;
margin: 5px;
padding: 10px;
}
.inner-div > ul > span {
display: inline;
}
.inner-div .acc-input {
position: absolute;
opacity: 0;
}
.inner-div .acc-input:checked ~ .acc-sub-cat {
display: block;
}
.inner-div .acc-sub-cat {
display: none;
overflow: hidden;
}
<div class="main-div" onclick="myFunction()"> Select Items
</div>
<div class="inner-div" id="myDIV">
<ul>
<li>
<input class="acc-input" type="checkbox" id="group-1">
<label for="group-1"><span>Group 1</span></label>
<ul class="acc-sub-cat">
<li><a><span>Item 1</span></a></li>
<li><a><span>Item 2</span></a></li>
</ul>
</li>
</ul>
</div>
但是我的代码片段并不像我需要的那样,而且我在 CSS 方面经验不多。
谁能帮我顺利达到想要的数字CSS,好吗?
PS:我没有使用 jquery
根据你的图片重写了很多代码。请看一下。
您可以从 .drop-box
中删除 .active
,这样菜单会在开始时折叠。
在按钮和菜单元素周围添加了 .drop-box
,使用 position: relative;
,因此使用 position: absolute;
的下拉菜单将取决于父位置。
.drop-button:after, .link:before
这些是箭头,它们在 .active
class 上旋转,如您所见。
已更新
现在 JS 支持在元素 drop-box
外部单击并关闭它(删除 .active
)。尽管您可以添加多个 .drop-box
具有我示例中结构的元素,但它们都将单独工作。
for (let dropbox of document.querySelectorAll('.drop-box')) {
let dropButton = dropbox.querySelector(".drop-button");
let dropMenu = dropbox.querySelector(".drop-menu");
document.body.addEventListener("click", function(e) {
let target = e.target || e.srcElement;
if (target !== dropbox && !isChildOf(target, dropbox)) {
dropbox.classList.remove("active");
}
}, false);
function isChildOf(child, parent) {
if (child.parentNode === parent) {
return true;
} else if (child.parentNode === null) {
return false;
} else {
return isChildOf(child.parentNode, parent);
}
}
dropButton.addEventListener("click", function(e) {
dropbox.classList.toggle("active");
for (let link of dropMenu.querySelectorAll('.link')) {
link.classList.remove("active");
}
}, false);
let xx = 0;
for (let link of dropMenu.querySelectorAll('.link')) {
(function(index){
link.addEventListener("click", function() {
let yy = 0;
for (let links of dropMenu.querySelectorAll('.link')) {
if (index !== yy) {
links.classList.remove("active");
}
yy++
}
this.classList.toggle("active");
})
})(xx);
xx++;
}
}
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
.drop-box {
position: relative;
display: inline-block;
}
.drop-button {
display: inline-block;
padding: 10px;
cursor: pointer;
border: 1px solid #000;
background: #fff;
}
.drop-button:after,
.link:before {
content: '';
border: 5px solid transparent;
border-top-color: #000;
box-sizing: border-box;
display: inline-block;
margin: 0 3px;
transform: rotate(-90deg);
}
.drop-box.active .drop-button:after,
.link.active:before {
transform: rotate(0deg);
}
.drop-menu {
display: none;
position: absolute;
width: 210px;
top: 100%;
left: 0px;
border: 1px solid #000;
background: #fff;
}
.drop-box.active .drop-menu {
display: block;
}
.drop-menu .link {
padding: 10px;
cursor: pointer;
}
.drop-menu .box {
display: none;
padding: 0 10px 10px 10px;
}
.drop-menu .link.active+.box {
display: block;
}
.drop-menu .box label {
display: block;
}
<div class="drop-box active">
<div class="drop-button">Select Items 1</div>
<div class="drop-menu">
<div class="link-box">
<div class="link">Group 1</div>
<div class="box">
<label><input type="checkbox" id="box-1"><span>Box 1</span></label>
<label><input type="checkbox" id="box-2"><span>Box 2</span></label>
</div>
</div>
<div class="link-box">
<div class="link">Group 2</div>
<div class="box">
<label><input type="checkbox" id="box-3"><span>Box 3</span></label>
<label><input type="checkbox" id="box-4"><span>Box 4</span></label>
</div>
</div>
</div>
</div>
<div class="drop-box">
<div class="drop-button">Select Items 2</div>
<div class="drop-menu ">
<div class="link-box">
<div class="link">Group 3</div>
<div class="box">
<label><input type="checkbox" id="box-5"><span>Box 5</span></label>
<label><input type="checkbox" id="box-6"><span>Box 6</span></label>
</div>
</div>
<div class="link-box">
<div class="link">Group 4</div>
<div class="box">
<label><input type="checkbox" id="box-7"><span>Box 7</span></label>
<label><input type="checkbox" id="box-8"><span>Box 8</span></label>
</div>
</div>
</div>
</div>
我正在尝试构建一个具有可折叠选项的自定义下拉菜单。 下拉菜单中的每个选项都会有子选项,选择后会给我值。
在摘要上,下拉菜单应如下所示:
考虑到以上想法,我已经通过 fiddle.
尝试了我的方法function myFunction() {
var x = document.getElementById("myDIV");
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
}
.main-div {
display: inline-block;
padding: 15px;
width: 180px;
cursor:pointer;
border: 1px solid salmon;
}
.inner-div {
position: absolute;
width: 210px;
top: 58px;
left: 8px;
height: 300px;
border: 1px solid salmon;
}
.inner-div > ul {
list-style-type: none;
border-bottom: 1px solid salmon;
margin: 5px;
padding: 10px;
}
.inner-div > ul > span {
display: inline;
}
.inner-div .acc-input {
position: absolute;
opacity: 0;
}
.inner-div .acc-input:checked ~ .acc-sub-cat {
display: block;
}
.inner-div .acc-sub-cat {
display: none;
overflow: hidden;
}
<div class="main-div" onclick="myFunction()"> Select Items
</div>
<div class="inner-div" id="myDIV">
<ul>
<li>
<input class="acc-input" type="checkbox" id="group-1">
<label for="group-1"><span>Group 1</span></label>
<ul class="acc-sub-cat">
<li><a><span>Item 1</span></a></li>
<li><a><span>Item 2</span></a></li>
</ul>
</li>
</ul>
</div>
但是我的代码片段并不像我需要的那样,而且我在 CSS 方面经验不多。 谁能帮我顺利达到想要的数字CSS,好吗?
PS:我没有使用 jquery
根据你的图片重写了很多代码。请看一下。
您可以从 .drop-box
中删除 .active
,这样菜单会在开始时折叠。
在按钮和菜单元素周围添加了 .drop-box
,使用 position: relative;
,因此使用 position: absolute;
的下拉菜单将取决于父位置。
.drop-button:after, .link:before
这些是箭头,它们在 .active
class 上旋转,如您所见。
已更新
现在 JS 支持在元素 drop-box
外部单击并关闭它(删除 .active
)。尽管您可以添加多个 .drop-box
具有我示例中结构的元素,但它们都将单独工作。
for (let dropbox of document.querySelectorAll('.drop-box')) {
let dropButton = dropbox.querySelector(".drop-button");
let dropMenu = dropbox.querySelector(".drop-menu");
document.body.addEventListener("click", function(e) {
let target = e.target || e.srcElement;
if (target !== dropbox && !isChildOf(target, dropbox)) {
dropbox.classList.remove("active");
}
}, false);
function isChildOf(child, parent) {
if (child.parentNode === parent) {
return true;
} else if (child.parentNode === null) {
return false;
} else {
return isChildOf(child.parentNode, parent);
}
}
dropButton.addEventListener("click", function(e) {
dropbox.classList.toggle("active");
for (let link of dropMenu.querySelectorAll('.link')) {
link.classList.remove("active");
}
}, false);
let xx = 0;
for (let link of dropMenu.querySelectorAll('.link')) {
(function(index){
link.addEventListener("click", function() {
let yy = 0;
for (let links of dropMenu.querySelectorAll('.link')) {
if (index !== yy) {
links.classList.remove("active");
}
yy++
}
this.classList.toggle("active");
})
})(xx);
xx++;
}
}
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
.drop-box {
position: relative;
display: inline-block;
}
.drop-button {
display: inline-block;
padding: 10px;
cursor: pointer;
border: 1px solid #000;
background: #fff;
}
.drop-button:after,
.link:before {
content: '';
border: 5px solid transparent;
border-top-color: #000;
box-sizing: border-box;
display: inline-block;
margin: 0 3px;
transform: rotate(-90deg);
}
.drop-box.active .drop-button:after,
.link.active:before {
transform: rotate(0deg);
}
.drop-menu {
display: none;
position: absolute;
width: 210px;
top: 100%;
left: 0px;
border: 1px solid #000;
background: #fff;
}
.drop-box.active .drop-menu {
display: block;
}
.drop-menu .link {
padding: 10px;
cursor: pointer;
}
.drop-menu .box {
display: none;
padding: 0 10px 10px 10px;
}
.drop-menu .link.active+.box {
display: block;
}
.drop-menu .box label {
display: block;
}
<div class="drop-box active">
<div class="drop-button">Select Items 1</div>
<div class="drop-menu">
<div class="link-box">
<div class="link">Group 1</div>
<div class="box">
<label><input type="checkbox" id="box-1"><span>Box 1</span></label>
<label><input type="checkbox" id="box-2"><span>Box 2</span></label>
</div>
</div>
<div class="link-box">
<div class="link">Group 2</div>
<div class="box">
<label><input type="checkbox" id="box-3"><span>Box 3</span></label>
<label><input type="checkbox" id="box-4"><span>Box 4</span></label>
</div>
</div>
</div>
</div>
<div class="drop-box">
<div class="drop-button">Select Items 2</div>
<div class="drop-menu ">
<div class="link-box">
<div class="link">Group 3</div>
<div class="box">
<label><input type="checkbox" id="box-5"><span>Box 5</span></label>
<label><input type="checkbox" id="box-6"><span>Box 6</span></label>
</div>
</div>
<div class="link-box">
<div class="link">Group 4</div>
<div class="box">
<label><input type="checkbox" id="box-7"><span>Box 7</span></label>
<label><input type="checkbox" id="box-8"><span>Box 8</span></label>
</div>
</div>
</div>
</div>