I have an accordion. When you click on the accordion header, it opens and the active class is added to the header. I need the active class to be added to the entire item of the accordion that is clicked on as well. How can i do this? I need to set the active class for "accordion-item"
const accordionItemHeaders = document.querySelectorAll(
".accordion-item-header"
);
accordionItemHeaders.forEach((accordionItemHeader) => {
accordionItemHeader.addEventListener("click", () => {
accordionItemHeader.classList.toggle("active");
const accordionItemBody = accordionItemHeader.nextElementSibling;
if (accordionItemHeader.classList.contains("active")) {
accordionItemBody.style.maxHeight = accordionItemBody.scrollHeight + "px";
} else {
accordionItemBody.style.maxHeight = 0;
}
});
});
<div class="question-content_accordion">
<div class="accordion-item">
<div class="accordion-item-header">
Title1
</div>
<div class="accordion-item-body">
<div class="accordion-item-body-content">
<p>Text1</p>
</div>
</div>
</div>
<div class="accordion-item">
<div class="accordion-item-header">
Title2
</div>
<div class="accordion-item-body">
<div class="accordion-item-body-content">
<p>Text2</p>
</div>
</div>
</div>
<div class="accordion-item">
<div class="accordion-item-header">
Title3
</div>
<div class="accordion-item-body">
<div class="accordion-item-body-content">
<p>Text3</p>
</div>
</div>
</div>
</div>
>Solution :
You probably want the .closest() method.
const accordionItemHeaders = document.querySelectorAll(
".accordion-item-header"
);
accordionItemHeaders.forEach((accordionItemHeader) => {
accordionItemHeader.addEventListener("click", () => {
accordionItemHeader.classList.toggle("active");
accordionItemHeader.closest(".accordion-item").classList.toggle("active"); // NEW
const accordionItemBody = accordionItemHeader.nextElementSibling;
if (accordionItemHeader.classList.contains("active")) {
accordionItemBody.style.maxHeight = accordionItemBody.scrollHeight + "px";
} else {
accordionItemBody.style.maxHeight = 0;
}
});
});
However, an alternative would be to use the details element since that will do everything you need it to without any JavaScript and add an open attribute when the contents are visible.
<div class="question-content_accortion">
<details class="accordion-item">
<summary class="accordion-item-body">Text1</summary>
<div class="accordion-item-body">
<div class="accordion-item-body-content">
<p>Text1</p>
</div>
</div>
</details>
<details class="accordion-item">
<summary class="accordion-item-body">Text2</summary>
<div class="accordion-item-body">
<div class="accordion-item-body-content">
<p>Text2</p>
</div>
</div>
</details>
<details class="accordion-item">
<summary class="accordion-item-body">Text3</summary>
<div class="accordion-item-body">
<div class="accordion-item-body-content">
<p>Text3</p>
</div>
</div>
</details>
</div>