C-delb
C-delb

Reputation: 31

JS - How can I make an accordion item close when another has been clicked on and opened?

I have added an accordion to an FAQ page on my website. I want to make it close the previously opened accordion item, so that only one accordion item is open at a time if that makes sense? My code is below. I tried playing around with remove class to remove the .active tag but can't seem to get it working.

const accordion = document.getElementsByClassName('contentBx');

for (i = 0; i < accordion.length; i++) {
  accordion[i].addEventListener('click', function() {
    this.classList.toggle('active')
    $('').not($(this).removeClass('active'));
  })
}
body {
  background: black
}

.accordion {
  max-width: 2000px;
  -webkit-box-align: center;
  -ms-flex-align: center;
  align-items: center;
  padding-left: 60px;
  padding-right: 60px;
  margin-top: 30px;
  margin-bottom: 30px;
}

@media (max-width: 820px) {
  .accordion {
    padding-left: 20px;
    padding-right: 20px;
  }
}

.accordion .contentBx {
  position: relative;
  margin-top: 10px;
}

.accordion .contentBx .accordion-label {
  position: relative;
  padding: 10px;
  background: var(--tertiary-color);
  color: white;
  cursor: pointer;
}

.accordion .contentBx .accordion-label::before {
  content: '+';
  position: absolute;
  top: 50%;
  right: 20px;
  -webkit-transform: translateY(-50%);
  transform: translateY(-50%);
}

.accordion .contentBx.active .accordion-label::before {
  content: '-';
}

.accordion .contentBx .accordion-content {
  position: relative;
  background: var(--background-medium-grey);
  height: 0;
  overflow: hidden;
  -webkit-transition: 0.5s;
  transition: 0.5s;
  overflow-y: auto;
}

.accordion .contentBx.active .accordion-content {
  height: -webkit-fit-content;
  height: -moz-fit-content;
  height: fit-content;
  padding: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section>
  <div class="accordion">
    <div class="contentBx">
      <div class="accordion-label">
        <p>Some text</p>
      </div>
      <div class="accordion-content">
        <p>Some text</p>
      </div>
    </div>
    <div class="contentBx">
      <div class="accordion-label">
        <p>Some text</p>
      </div>
      <div class="accordion-content">
        <p>Some text</p>
      </div>
    </div>
    <div class="contentBx">
      <div class="accordion-label">
        <p>Some text</p>
      </div>
      <div class="accordion-content">
        <p>Some text</p>
      </div>
    </div>
    <div class="contentBx">
      <div class="accordion-label">
        <p>Some text</p>
      </div>
      <div class="accordion-content">
        <p>Some text</p>
      </div>
    </div>
</section>

Upvotes: 1

Views: 114

Answers (1)

Mina
Mina

Reputation: 17049

const accordion = document.getElementsByClassName('contentBx');

for (i = 0; i < accordion.length; i++) {
  accordion[i].addEventListener('click', function() {
    [...accordion].forEach(item => {
      if (item !== this) 
        item.classList.remove('active')
    }, this)
    this.classList.toggle('active')
  })
}
body {
  background: black
}

.accordion {
  max-width: 2000px;
  -webkit-box-align: center;
  -ms-flex-align: center;
  align-items: center;
  padding-left: 60px;
  padding-right: 60px;
  margin-top: 30px;
  margin-bottom: 30px;
}

@media (max-width: 820px) {
  .accordion {
    padding-left: 20px;
    padding-right: 20px;
  }
}

.accordion .contentBx {
  position: relative;
  margin-top: 10px;
}

.accordion .contentBx .accordion-label {
  position: relative;
  padding: 10px;
  background: var(--tertiary-color);
  color: white;
  cursor: pointer;
}

.accordion .contentBx .accordion-label::before {
  content: '+';
  position: absolute;
  top: 50%;
  right: 20px;
  -webkit-transform: translateY(-50%);
  transform: translateY(-50%);
}

.accordion .contentBx.active .accordion-label::before {
  content: '-';
}

.accordion .contentBx .accordion-content {
  position: relative;
  background: var(--background-medium-grey);
  height: 0;
  overflow: hidden;
  -webkit-transition: 0.5s;
  transition: 0.5s;
  overflow-y: auto;
}

.accordion .contentBx.active .accordion-content {
  height: -webkit-fit-content;
  height: -moz-fit-content;
  height: fit-content;
  padding: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section>
  <div class="accordion">
    <div class="contentBx">
      <div class="accordion-label">
        <p>Some text</p>
      </div>
      <div class="accordion-content">
        <p>Some text</p>
      </div>
    </div>
    <div class="contentBx">
      <div class="accordion-label">
        <p>Some text</p>
      </div>
      <div class="accordion-content">
        <p>Some text</p>
      </div>
    </div>
    <div class="contentBx">
      <div class="accordion-label">
        <p>Some text</p>
      </div>
      <div class="accordion-content">
        <p>Some text</p>
      </div>
    </div>
    <div class="contentBx">
      <div class="accordion-label">
        <p>Some text</p>
      </div>
      <div class="accordion-content">
        <p>Some text</p>
      </div>
    </div>
</section>

Upvotes: 0

Related Questions