另一个打开手风琴面板时如何关闭?

时间:2019-03-26 18:21:30

标签: javascript html css

我在静态HTML / CSS / JS网站上有手风琴小部件。

默认情况下,所有手风琴都是关闭的。

用户可以打开它们中的任何一个,直到用户通过单击手风琴标题手动将其关闭之前,它们将保持打开状态。

当用户单击以打开另一只手风琴时,如何使其关闭?

我使用以下模板创建了手风琴:https://www.w3schools.com/howto/tryit.asp?filename=tryhow_js_accordion_animate

我在HTML文件中同时放入了HTML和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";
}
});
}
.accordion {
  color: #fff;
  background-color: #00000042;
  cursor: pointer;
  padding: 10px 10px;
  margin-top:20px;
  width: 100%;
  border: 1px solid #00000042;
  text-align: left;
  outline: none;
  transition: 0.4s;
}

.active, .accordion:hover {
  background-color: #00000042;
  border: 1px solid #fc8e2d;
}

.panel {
  padding: 0 18px;
  font-size: 18px;
  background-color: #00000042;
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.3s ease-out;
}
<button class="accordion"><span class="faq__question-heading">Title1</span></button>
<div class="panel">
  <p style="padding:18px 0;">description1</p>
</div>

<button class="accordion"><span class="faq__question-heading">Title2</span></button>
<div class="panel">
  <p style="padding:18px 0;">description2</p>
</div>

<button class="accordion"><span class="faq__question-heading">Title3</span></button>
<div class="panel">
  <p style="padding:18px 0;">description3</p>
</div>

<script>

</script>

4 个答案:

答案 0 :(得分:0)

只需将maxHeight内其他<script>属性重置为空,即可:

<!DOCTYPE html>
<html>

<head>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <style>
    .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: #ccc;
    }
    
    .panel {
      padding: 0 18px;
      background-color: white;
      max-height: 0;
      overflow: hidden;
      transition: max-height 0.2s ease-out;
    }
  </style>
</head>

<body>

  <h2>Animated Accordion</h2>
  <p>Click on the buttons to open the collapsible content.</p>

  <button class="accordion">Section 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">Section 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>
  </div>

  <button class="accordion">Section 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>

  <script>
    var acc = document.getElementsByClassName("accordion");

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

</body>

</html>

答案 1 :(得分:0)

您还可以在click事件处理程序中使用一个以上的for循环来重置高度。如果手风琴被打开,它也会关闭。

for (var j = 0; j < acc.length; j++) {
    acc[j].nextElementSibling.style.maxHeight = null;
}

请参见下面的代码段

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

for (let i = 0; i < acc.length; i++) {
  acc[i].addEventListener("click", function() {
    for (let j = 0; j < acc.length; j++) {
    acc[j].classList.remove("active");
      if(j!=i){
        acc[j].nextElementSibling.style.maxHeight = null;
      }
    }
    this.classList.add("active");
    var panel = this.nextElementSibling;
    if (panel.style.maxHeight){
      panel.style.maxHeight = null;
    } else {
      panel.style.maxHeight = panel.scrollHeight + "px";
    }
  });
}
.accordion {
  color: #fff;
  background-color: #00000042;
  cursor: pointer;
  padding: 10px 10px;
  margin-top:20px;
  width: 100%;
  border: 1px solid #00000042;
  text-align: left;
  outline: none;
  transition: 0.4s;
}

.active, .accordion:hover {
  background-color: #00000042;
  border: 1px solid #fc8e2d;
}

.panel {
  padding: 0 18px;
  font-size: 18px;
  background-color: #00000042;
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.3s ease-out;
}
<button class="accordion"><span class="faq__question-heading">Title1</span></button>
<div class="panel">
  <p style="padding:18px 0;">description1</p>
</div>

<button class="accordion"><span class="faq__question-heading">Title2</span></button>
<div class="panel">
  <p style="padding:18px 0;">description2</p>
</div>

<button class="accordion"><span class="faq__question-heading">Title3</span></button>
<div class="panel">
  <p style="padding:18px 0;">description3</p>
</div>

<script>

</script>

答案 2 :(得分:0)

在我完成代码时已经给出了一些答案;)。但是我还是会做贡献。每次打开手风琴,您都必须执行一些额外的代码。您必须获取具有类.active的元素-在您的情况下,我们将使用.accordion.active。之后,有必要从找到的元素中删除.active类。最后,您必须更新以下面板的max-height。您可以使用nextElementSilbling进行此操作。这是更新的JS代码:

  let active = document.querySelectorAll(".accordion-div .accordion.active");
  for(let j = 0; j < active.length; j++){
    active[j].classList.remove("active");
    active[j].nextElementSibling.style.maxHeight = null; //or 0px
  }

此外,我更新了HTML以更好地封装该组件。我将<div>包裹在所有内容上,以更好地应用选择器来检索元素。希望这可以帮助。我复制了您的答案并对其进行了更新,以生成一个有效的示例。如果您希望每页使用多个手风琴,我建议您与id=一起使用以检索正确的手风琴。否则,所有手风琴都会关闭,这不是故意发生的。

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

for (i = 0; i < acc.length; i++) {
acc[i].addEventListener("click", function() {

var panel = this.nextElementSibling;
if (panel.style.maxHeight){
  panel.style.maxHeight = null;
} else {
  let active = document.querySelectorAll(".accordion-div .accordion.active");
  for(let j = 0; j < active.length; j++){
    active[j].classList.remove("active");
    active[j].nextElementSibling.style.maxHeight = null;
  }
  this.classList.toggle("active");
  panel.style.maxHeight = panel.scrollHeight + "px";
}
});
}
.accordion {
  color: #fff;
  background-color: #00000042;
  cursor: pointer;
  padding: 10px 10px;
  margin-top:20px;
  width: 100%;
  border: 1px solid #00000042;
  text-align: left;
  outline: none;
  transition: 0.4s;
}

.active, .accordion:hover {
  background-color: #00000042;
  border: 1px solid #fc8e2d;
}

.panel {
  padding: 0 18px;
  font-size: 18px;
  background-color: #00000042;
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.3s ease-out;
}
<div class="accordion-div">
  <button class="accordion"><span class="faq__question-heading">Title1</span></button>
  <div class="panel">
    <p style="padding:18px 0;">description1</p>
  </div>

  <button class="accordion"><span class="faq__question-heading">Title2</span></button>
  <div class="panel">
    <p style="padding:18px 0;">description2</p>
  </div>

  <button class="accordion"><span class="faq__question-heading">Title3</span></button>
  <div class="panel">
    <p style="padding:18px 0;">description3</p>
  </div>
</div>

<script>

</script>

答案 3 :(得分:-1)

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

for (i = 0; i < acc.length; i++) {
acc[i].addEventListener("click", function() {
this.classList.toggle("active");

// init: close all accordions
var allAcc = document.getElementsByClassName("accordion");
for (var e = 0; e < allAcc.length; e++) {
  var aPanel = allAcc[e].nextElementSibling;
  aPanel.style.maxHeight = null;
}

var panel = this.nextElementSibling;
if (panel.style.maxHeight){
  panel.style.maxHeight = null;
} else {
  panel.style.maxHeight = panel.scrollHeight + "px";
}
});
}

编辑: 我在注释“ // init:关闭所有手风琴”之后添加了5行。 正如评论所言,这些行关闭了所有手风琴。这是通过使所有元素具有“手风琴”类来完成的。通过遍历这些元素,可以使用保存了手风琴描述的面板div(手风琴元素的下一个兄弟元素)。此面板元素的高度设置为“ null”-因此没有高度(类似于“ invisible”或“ display:none”)。 我之所以使用此代码,是因为在有人单击手风琴时,问询者的代码中也使用它来关闭面板。