how to add class to accordion element?

Viewed 26

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>

1 Answers

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>

Related