Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript accordian - collapse all open instances except active

I am using a simple javascript accordion to open/close list items as follows. Is it possible to make sure ALL open list items close when a new one is opened (instead of the current way which leaves every list item open until it is manually closed)?

CODEPEN HERE:

https://codepen.io/anon/pen/zejJpJ

JS

var acc = document.getElementsByClassName("accordion");
var i;

for (i = 0; i < acc.length; i++) {
    acc[i].addEventListener("click", function () {
        this.classList.toggle("active");
        var panel = this.nextElementSibling;
        if (panel.style.maxHeight) {
            panel.style.maxHeight = null;
        } else {
            panel.style.maxHeight = panel.scrollHeight + "px";
        }
    });
}

HTML

<ul class="track-listing">
  <li>
    <button class="accordion">TITLE</button>
    <div class="panel">
    <p>Panel content</p>
    </div>
  </li>
  <li>
    <button class="accordion">TITLE</button>
    <div class="panel">
    <p>Panel content</p>
    </div>
  </li>
  <li>
    <button class="accordion">TITLE</button>
    <div class="panel">
    <p>Panel content</p>
    </div>
  </li>
</ul>
like image 654
lowercase Avatar asked Mar 04 '23 13:03

lowercase


1 Answers

Yes you can, by closing all other accordions before opening a new one:

for (var j = 0; j < acc.length; j++) {
  var button = acc[j];

  if (button === this) continue;

  button.classList.remove("active");
  var panel = button.nextElementSibling;
  panel.style.maxHeight = null;
}

var acc = document.getElementsByClassName("accordion");

for (var i = 0; i < acc.length; i++) {
  acc[i].addEventListener("click", function() {
    // Close all other accordions
    for (var j = 0; j < acc.length; j++) {
      var button = acc[j];
      
      if (button === this) continue;
      
      button.classList.remove("active");
      var panel = button.nextElementSibling;
      panel.style.maxHeight = null;
    }

    this.classList.toggle("active");
    var panel = this.nextElementSibling;
    
    if (panel.style.maxHeight) {
      panel.style.maxHeight = null;
    } else {
      panel.style.maxHeight = panel.scrollHeight + "px";
    }
  });
}
.accordion {
  background-color: #1e1e1e;
  color: #c0b9b4;
  cursor: pointer;
  padding: 18px;
  width: 100%;
  border: none;
  text-align: left;
  outline: none;
  font-size: 1em;
  transition: 0.4s;
  margin: 0 0 2px 0;
}

ul.track-listing {
  padding: 0;
  margin: 0;
  list-style-type: none;
}

.active,
.accordion:hover {
  background-color: #c0b9b4;
  color: #1e1e1e;
}

.accordion:after {
  content: 'LYRICS \002B ';
  color: #777;
  float: right;
  margin-left: 5px;
}

.active:after {
  content: "\2212";
}

.panel {
  padding: 0 18px;
  background-color: #1e1e1e;
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.2s ease-out;
  color: #c0b9b4;
}
<ul class="track-listing">
  <li>
    <button class="accordion">TITLE</button>
    <div class="panel">
      <p>Panel content</p>
    </div>
  </li>
  <li>
    <button class="accordion">TITLE</button>
    <div class="panel">
      <p>Panel content</p>
    </div>
  </li>
  <li>
    <button class="accordion">TITLE</button>
    <div class="panel">
      <p>Panel content</p>
    </div>
  </li>
</ul>
like image 72
sn3p Avatar answered Apr 06 '23 08:04

sn3p