单击同一问题时关闭 FAQ 手风琴

时间:2021-05-07 19:10:10

标签: javascript html jquery css

我用 HTML/JS 创建了一个手风琴。一切正常,但是当我单击一个问题时,它会展开面板,但是当我再次单击相同的问题时它不会关闭。

我使用 W3Schools 教程创建了这个脚本 - https://www.w3schools.com/howto/howto_js_accordion.asp

这是我的代码 -

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

for (i = 0; i < acc.length; i++) {
  acc[i].addEventListener("click", function() {
    for (j = 0; j < acc.length; j++) {
      acc[j].nextElementSibling.style.maxHeight = null;
    }
    this.classList.toggle("accordion1:active");
    var panel = this.nextElementSibling;
    if (panel.style.maxHeight) {
      panel.style.maxHeight = null;
    } else {
      panel.style.maxHeight = panel.scrollHeight + "px";
    }
  });
}
.accordion1 {
  background-color: #fff;
  color: #444;
  padding: 18px;
  width: 100%;
  border: none;
  text-align: left;
  outline: none;
  font-size: 14px;
  transition: .4s
}

.accordion1:active,
.accordion1:hover {
  background-color: #5d4b79;
  color: #fff
}

.accordion1:after {
  content: '\002B';
  color: #fff;
  font-weight: 700;
  float: right;
  margin-left: 5px
}

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

.panel1 {
  padding: 0 18px;
  background-color: #fff;
  max-height: 0;
  overflow: hidden;
  transition: max-height .2s ease-out
}
<button class="accordion1">Question 1</button>
<div class="panel1">
  <p>Answer 1</p>
</div>

<button class="accordion1">Question 2</button>
<div class="panel1">
  <p>Answer 2</p>
</div>

<button class="accordion1">Question 3</button>
<div class="panel1">
  <p>Answer 3</p>
</div>

感谢任何帮助。

2 个答案:

答案 0 :(得分:2)

您需要更改一些代码。 Jonah Walker 已经解决了这个问题。 这是Codepen Link

他已经评论了他的代码。希望您的问题得到解决。

 var acc = document.getElementsByClassName("accordion");
  var i;
  
  // Open the first accordion
  var firstAccordion = acc[0];
  var firstPanel = firstAccordion.nextElementSibling;
  firstAccordion.classList.add("active");
  firstPanel.style.maxHeight = firstPanel.scrollHeight + "px";

  // Add onclick listener to every accordion element
  for (i = 0; i < acc.length; i++) {
    acc[i].onclick = function() {
      // For toggling purposes detect if the clicked section is already "active"
      var isActive = this.classList.contains("active");

      // Close all accordions
      var allAccordions = document.getElementsByClassName("accordion");
      for (j = 0; j < allAccordions.length; j++) {
        // Remove active class from section header
        allAccordions[j].classList.remove("active");

        // Remove the max-height class from the panel to close it
        var panel = allAccordions[j].nextElementSibling;
        var maxHeightValue = getStyle(panel, "maxHeight");
      
      if (maxHeightValue !== "0px") {
          panel.style.maxHeight = null;
        }
      }

      // Toggle the clicked section using a ternary operator
      isActive ? this.classList.remove("active") : this.classList.add("active");

      // Toggle the panel element
      var panel = this.nextElementSibling;
      var maxHeightValue = getStyle(panel, "maxHeight");
      
      if (maxHeightValue !== "0px") {
        panel.style.maxHeight = null;
      } else {
        panel.style.maxHeight = panel.scrollHeight + "px";
      }
    };
  }
  
  // Cross-browser way to get the computed height of a certain element. Credit to @CMS on StackOverflow (http://stackoverflow.com/a/2531934/7926565)
  function getStyle(el, styleProp) {
  var value, defaultView = (el.ownerDocument || document).defaultView;
  // W3C standard way:
  if (defaultView && defaultView.getComputedStyle) {
    // sanitize property name to css notation
    // (hypen separated words eg. font-Size)
    styleProp = styleProp.replace(/([A-Z])/g, "-$1").toLowerCase();
    return defaultView.getComputedStyle(el, null).getPropertyValue(styleProp);
  } else if (el.currentStyle) { // IE
    // sanitize property name to camelCase
    styleProp = styleProp.replace(/\-(\w)/g, function(str, letter) {
      return letter.toUpperCase();
    });
    value = el.currentStyle[styleProp];
    // convert other units to pixels on IE
    if (/^\d+(em|pt|%|ex)?$/i.test(value)) { 
      return (function(value) {
        var oldLeft = el.style.left, oldRsLeft = el.runtimeStyle.left;
        el.runtimeStyle.left = el.currentStyle.left;
        el.style.left = value || 0;
        value = el.style.pixelLeft + "px";
        el.style.left = oldLeft;
        el.runtimeStyle.left = oldRsLeft;
        return value;
      })(value);
    }
    return value;
  }
}
button.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;
}

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

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

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

div.panel {
    padding: 0 18px;
    background-color: white;
    max-height: 0;
    overflow: hidden;
    transition: max-height 0.2s ease-out;
}
    <button class="accordion">Question 1</button>
<div class="panel">
  <p>Answer 1</p>
</div>

<button class="accordion">Question 2</button>
<div class="panel">
  <p>Answer 2</p>
</div>

<button class="accordion">Question 3</button>
<div class="panel">
  <p>Answer 3</p>
</div>

答案 1 :(得分:0)

我建议您使用一个类来设置最大高度,因为您已经为类 .panel1 设置了 max-height: 0,您可以添加另一个设置 max-height: none 的类,以便在显示面板时使用。< /p>

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

for (i = 0; i < acc.length; i++) {
  acc[i].addEventListener("click", function() {
    for (j = 0; j < acc.length; j++) {
      acc[j].nextElementSibling.classList.remove("panelactive");
    }
    this.classList.toggle("accordion1:active");
    var panel = this.nextElementSibling;
    panel.classList.toggle("panelactive");
  });
}
.accordion1 {
  background-color: #fff;
  color: #444;
  padding: 18px;
  width: 100%;
  border: none;
  text-align: left;
  outline: none;
  font-size: 14px;
  transition: .4s
}

.accordion1:active,
.accordion1:hover {
  background-color: #5d4b79;
  color: #fff
}

.accordion1:after {
  content: '\002B';
  color: #fff;
  font-weight: 700;
  float: right;
  margin-left: 5px
}

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

.panel1 {
  padding: 0 18px;
  background-color: #fff;
  max-height: 0;
  overflow: hidden;
  transition: max-height .2s ease-out
}
.panelactive {
  max-height: none;
}
<button class="accordion1">Question 1</button>
<div class="panel1">
  <p>Answer 1</p>
</div>

<button class="accordion1">Question 2</button>
<div class="panel1">
  <p>Answer 2</p>
</div>

<button class="accordion1">Question 3</button>
<div class="panel1">
  <p>Answer 3</p>
</div>