Javascript手风琴关闭页眉/面板(如果选中)

时间:2019-03-08 16:42:15

标签: javascript html css

如果要单击相同的标题/面板,我希望手风琴关闭,如果选择了新的标题/面板,我添加的功能将隐藏先前的面板,但是不会隐藏自身。

不想使用任何jquery,希望它保持纯javascript

我添加了另一个函数hide(),但是还没有成功,我需要在hide()中进行什么更改才能使其工作,或者可以全部通过for循环来完成?

function accordion() {
  let acc = document.getElementsByClassName("accordion")
  let i;

  for (i = 0; i < acc.length; i++) {
    acc[i].addEventListener("click", function() {
      hide()
      this.classList.toggle("active")
      let panel = this.nextElementSibling;
      if (panel.style.display == "block") {
        panel.style.display = "none"
      } else {
        panel.style.display = "block"
      }
    })
  }

  function hide() {
    for (i = 0; i < acc.length; i++) {
      acc[i].classList.toggle("active", false);
      acc[i].nextElementSibling.classList.toggle("show", false);
      acc[i].nextElementSibling.style.display = "none"
    }
  }
}
.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;
  display: none;
  background-color: white;
  overflow: hidden;
}
<body onload="accordion()">

<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>

</body>

3 个答案:

答案 0 :(得分:1)

我使用forEach()和三进制简化了您的代码。

  

问题是您在hide()函数中隐藏了所有手风琴,但是您不应该隐藏当前打开的手风琴,因此您可以简单地切换其状态。

document.querySelectorAll('.accordion').forEach((acc, i, all) => {
  acc.addEventListener('click', () => {
    hideOthers(acc);
    acc.classList.toggle('active');
    const panelStyle = acc.nextElementSibling.style;
    panelStyle.display = panelStyle.display === 'block' ? 'none' : 'block';
  })

  function hideOthers(me) {
    all.forEach(acc => {
      if (acc !== me) {
        acc.classList.remove('active');
        acc.nextElementSibling.classList.remove('show');
        acc.nextElementSibling.style.display = 'none';
      }
    });
  }
});
.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;
  display: none;
  background-color: white;
  overflow: hidden;
}
<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>

答案 1 :(得分:1)

您将需要跟踪当前单击的<div>。另外,您可以将css组合器+用作.active+.panel。参见下面的代码

function accordion() {
  let acc = document.querySelectorAll(".accordion")

  for (let i = 0; i < acc.length; i++) {
    acc[i].addEventListener("click", function() {
      for (let j = 0; j < acc.length; j++) {
        if (j !== i)
          acc[j].classList.remove("active")
      }
      this.classList.toggle("active")
    })
  }
}
.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;
  display: none;
  background-color: white;
  overflow: hidden;
}

.active+.panel {
  display: block;
}
<body onload="accordion()">

  <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>

</body>

答案 2 :(得分:1)

您可以简化代码:

  1. css:.active + .panel-> Adjacent sibling,因此您无需为此部分使用javascript。

  2. 在监听器中记住当前是否处于活动状态,如果不是,则“激活”它

function accordion(){
  let acc = document.getElementsByClassName("accordion")
  let i;

    for (i = 0; i < acc.length; i++) {
      acc[i].addEventListener("click", function() {
	let currentActive = this.classList.contains("active");
        hide();
        !currentActive && this.classList.add("active");
      })
    }

    function hide() {
        for (i = 0; i < acc.length; i++) {
            acc[i].classList.remove("active");
        }
    }

}
.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;
             display: none;
             background-color: white;
             overflow: hidden;
           }
	.active + .panel {
		display: block;
	}
<body onload="accordion()">

<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>



</body>