【问题标题】:Make accordion item open by default使手风琴项默认打开
【发布时间】:2022-09-27 15:43:48
【问题描述】:
在我的手风琴集中,我试图在页面加载时默认打开第一个手风琴项目。
我正在将类 .open 添加到该元素,如下所示:
<button class=\"open\">
这似乎可行,但问题是当我单击同一个元素而不是关闭它时,它会不断重新打开它并且通过查看 JS 脚本我不太明白可能是什么问题。
演示
var accordionButton = document.querySelectorAll(\"button\");
for (var i = 0; i < accordionButton.length; i++) {
accordionButton[i].addEventListener(\"click\", switchClasses);
}
function switchClasses() {
for (var i = 0; i < accordionButton.length; i++) {
if (this !== accordionButton[i]) {
accordionButton[i].classList.remove(\"open\");
accordionButton[i].nextElementSibling.style.maxHeight = null;
}
}
this.classList.toggle(\"open\");
var nextAccordionButton = this.nextElementSibling;
if (nextAccordionButton.style.maxHeight) {
nextAccordionButton.style.maxHeight = null;
} else {
nextAccordionButton.style.maxHeight =
nextAccordionButton.scrollHeight + \"px\";
}
}
.accordion-item {
border: 1px solid lightgrey;
}
button {
background: none;
border: none;
width: 100%;
max-width: none;
height: auto;
padding: 12px;
text-align: left;
cursor: pointer;
transition: 0.5s;
}
.content-wrapper {
max-height: 0;
overflow: hidden;
transition: max-height 0.2s ease-out;
}
.content {
padding: 0 10px;
}
.open {
background: lightgray;
border-bottom: none;
}
.open + .content-wrapper {
max-height: none;
}
<div class=\"accordion-item\">
<button class=\"open\">
<span class=\"accordion__title\">Accordion 1</span>
</button>
<div class=\"content-wrapper\">
<div class=\"content\">
<p>Accordion 1 content.
</div>
</div>
</div>
<div class=\"accordion-item\">
<button>
<span class=\"accordion__title\">Accordion 2</span>
</button>
<div class=\"content-wrapper\">
<div class=\"content\">
<p>Accordion 2 content.
</div>
</div>
</div>
<div class=\"accordion-item\">
<button>
<span class=\"accordion__title\">Accordion 3</span>
</button>
<div class=\"content-wrapper\">
<div class=\"content\">
<p>Accordion 3 content.
</div>
</div>
</div>
标签:
javascript
css
accordion
【解决方案1】:
您还必须检查当前单击的元素。发生的事情是,您在删除元素后不断地重新将open 应用到该元素。
此外,尝试将const 用于不会重新分配的变量。和let 用于将被变异的变量。
不建议使用var 关键字。
const accordionButton = document.querySelectorAll('button');
for (let i = 0; i < accordionButton.length; i++) {
accordionButton[i].addEventListener('click', switchClasses);
}
function switchClasses() {
for (let i = 0; i < accordionButton.length; i++) {
if (this !== accordionButton[i]) {
accordionButton[i].classList.remove('open');
accordionButton[i].nextElementSibling.style.maxHeight = null;
continue;
}
if (this === accordionButton[i]) {
if (!this.classList.contains('open')) {
this.classList.add('open');
const nextAccordionButton = this.nextElementSibling;
nextAccordionButton.style.maxHeight =
nextAccordionButton.scrollHeight + 'px';
} else {
accordionButton[i].classList.remove('open');
accordionButton[i].nextElementSibling.style.maxHeight = null;
}
}
}
}
.accordion-item {
border: 1px solid lightgrey;
}
button {
background: none;
border: none;
width: 100%;
max-width: none;
height: auto;
padding: 12px;
text-align: left;
cursor: pointer;
transition: 0.5s;
}
.content-wrapper {
max-height: 0;
overflow: hidden;
transition: max-height 0.2s ease-out;
}
.content {
padding: 0 10px;
}
.open {
background: lightgray;
border-bottom: none;
}
.open+.content-wrapper {
max-height: none;
}
<div class="accordion-item">
<button class="open">
<span class="accordion__title">Accordion 1</span>
</button>
<div class="content-wrapper">
<div class="content">
<p>Accordion 1 content.</p>
</div>
</div>
</div>
<div class="accordion-item">
<button>
<span class="accordion__title">Accordion 2</span>
</button>
<div class="content-wrapper">
<div class="content">
<p>Accordion 2 content.</p>
</div>
</div>
</div>
<div class="accordion-item">
<button>
<span class="accordion__title">Accordion 3</span>
</button>
<div class="content-wrapper">
<div class="content">
<p>Accordion 3 content.</p>
</div>
</div>
</div>
【解决方案2】:
这是一个简单的手风琴示例,可以简化您的问题/结构。
单击时,如果单击的元素具有类,我将删除 open。否则,如果打开手风琴,我会删除该类,然后打开单击的手风琴。
document.querySelectorAll("button").forEach((e) => {
e.addEventListener("click", () => {
if (e.classList.contains("open")) {
e.classList.remove("open")
} else {
let opened = document.querySelector("button.open")
if (opened) {
opened.classList.remove("open")
}
e.classList.add("open")
}
})
});
.content {
display: none;
}
button {
display: block;
}
.open {
background-color: orange;
}
.open+.content {
display: block;
}
<button class="open">Accordion 1</button>
<div class="content">Content 1</div>
<button>Accordion 2</button>
<div class="content">Content 2</div>
<button>Accordion 3</button>
<div class="content">Content 3</div>
此外,如果您想允许同时打开多个手风琴,您可以使用checkboxes 仅使用 HTML 和 CSS 进行设置。
input {
display: none;
}
label {
display: block;
width: fit-content;
}
input:checked+label {
background-color: orange;
}
.content {
display: none;
}
input:checked+label+.content {
display: block;
}
<input type="checkbox" id="accordion-1" checked/>
<label class="btn" for="accordion-1">Accordion 1</label>
<div class="content">Content 1</div>
<input type="checkbox" id="accordion-2" />
<label class="btn" for="accordion-2">Accordion 2</label>
<div class="content">Content 2</div>
<input type="checkbox" id="accordion-3" />
<label class="btn" for="accordion-3">Accordion 3</label>
<div class="content">Content 3</div>