Javascript accordian - свернуть все открытые экземпляры, кроме активных - PullRequest
0 голосов
/ 12 февраля 2019

Я использую простой javascript accordian для открытия / закрытия элементов списка следующим образом.Можно ли удостовериться, что ВСЕ открытые элементы списка закрываются при открытии нового (вместо текущего способа, при котором каждый элемент списка остается открытым, пока он не будет закрыт вручную)?

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>

Ответы [ 3 ]

0 голосов
/ 12 февраля 2019

Да, вы можете, закрыв все остальные аккордеоны перед открытием нового:

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>
0 голосов
/ 12 февраля 2019

Вы можете сделать это с помощью функции переключения, которая может быть переопределена в определенном закрытом состоянии.Таким образом, вы просто закрываете все, кроме нажатого, перед переключением.Вот раздвоенная ручка , с кодом ниже.

var acc = document.getElementsByClassName("accordion")

const toggleAccordian = (acc, open = !acc.classList.contains('active')) => {  
  acc.classList.toggle('active', open)
  const panel = acc.nextElementSibling
  panel.style.maxHeight = open ? panel.scrollHeight + "px" : null  
}

const elems = Array.from(acc)
elems.forEach(a => {
  a.addEventListener('click', () => {
    elems
      .filter(e => e !== a)
      .forEach(e => toggleAccordian(e, false))
    toggleAccordian(a)
  })
})
0 голосов
/ 12 февраля 2019

Да, вы можете перебрать массив acc еще раз и закрыть аккордеоны, индекс которых не совпадает с индексом закрытия.

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

for (i = 0; i < acc.length; i++) {
    acc[i].addEventListener("click", function () {
        toggleAccordion(this);
        if (this.classList.contains("active")) {
          for (var j = 0; j < acc.length; j++) {
            if (i != j) {
              acc[j].nextElementSibling.style.maxHeight = null;
            }
          }
        }
    });
}

function toggleAccordion(button) {
  button.classList.toggle("active");
  var panel = button.nextElementSibling;
  if (panel.style.maxHeight) {
    panel.style.maxHeight = null;
  } else {
    panel.style.maxHeight = panel.scrollHeight + "px";
  }
}
...