首页 > 解决方案 > 仅向单击的手风琴面板添加或删除类

问题描述

我需要一些帮助来修复手风琴组件中的错误:

  1. 在下面的示例中,请单击面板 1 打开并再次单击面板 1 将其关闭。
  2. 然后单击面板 2。您将看到面板 1 和面板 2 同时激活类,这是错误的。应仅将活动类添加或删除到单击的手风琴面板中。

请注意,我需要保持相同的功能,即手风琴面板在另一个打开时折叠。

您的帮助和指导将不胜感激。谢谢你。

var acc = document.getElementsByClassName("accordion");
var i;
var prevExpandedPanel = null;
for (i = 0; i < acc.length; i++) {
  acc[i].addEventListener("click", function() {
    if (prevExpandedPanel && this !== prevExpandedPanel) {  
      prevExpandedPanel.classList.toggle("active");
      prevExpandedPanel.nextElementSibling.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";
    } 
    prevExpandedPanel = this;
  });
}
.accordion {
  background-color: #eee;
  color: #444;
  cursor: pointer;
  padding: 18px;
  width: 100%;
  border: none;
  text-align: left;
  outline: none;
  font-size: 15px;
  transition: 0.4s;
}

.active, .accordion:hover {
  background-color: #f8f8f8;
}

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

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

.panel {
  padding: 0 18px;
  background-color: white;
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.2s ease-out;
}
<button class="accordion">Panel 1</button>
<div class="panel">
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
</div>

<button class="accordion">Panel 2</button>
<div class="panel">
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p><p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
</div>

<button class="accordion">Panel 3</button>
<div class="panel">
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
</div>

标签: javascripthtmlcssaccordioncollapse

解决方案


一个潜在的解决方案可能如下:

const accordionButtons = document.querySelectorAll(".accordion");

/* 
 * create an array of object associating the `button.accordion`
 * with the corresponding `div.panel`
 * (this is not strictly necessary, I just find it convenient)
 */
const accordions = []
accordionButtons.forEach(button => {
  accordions.push({
    btnEl: button,
    panelEl: button.nextElementSibling
  })
});

/*
 * create a function to handle the accordions toggle
 */
function expandSingle(accordion) {
  const isExpanded = accordion.btnEl.classList.contains('active');
  
  // 1. remove the active class from all accordions
  //    and set the max-height of all panels to 0
  accordions.forEach(item => {
    item.btnEl.classList.remove('active');
    item.panelEl.style.maxHeight = 0;
  });
  
  // 2. if the selected accordion was not already active/expanded
  //    add the active class to it and set the max-height
  if (!isExpanded) {
    accordion.btnEl.classList.add('active');
    accordion.panelEl.style.maxHeight = accordion.panelEl.scrollHeight + 'px';
  }
}

/*
 * add an event listener to each `button.accordion`, calling the function
 * which handles the accordions toggle
 */
accordions.forEach(accordion => {
  accordion.btnEl.addEventListener('click', () => expandSingle(accordion))
})
.accordion {
  background-color: #eee;
  color: #444;
  cursor: pointer;
  padding: 18px;
  width: 100%;
  border: none;
  text-align: left;
  outline: none;
  font-size: 15px;
  transition: 0.4s;
}

.active, .accordion:hover {
  background-color: #f8f8f8;
}

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

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

.panel {
  padding: 0 18px;
  background-color: white;
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.2s ease-out;
}
<button class="accordion">Panel 1</button>
<div class="panel">
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
</div>

<button class="accordion">Panel 2</button>
<div class="panel">
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p><p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
</div>

<button class="accordion">Panel 3</button>
<div class="panel">
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
</div>


推荐阅读