[英]Creating a toggle button for expanding and collapsing an Accordion
I created a modified accordion for a FAQ page I am working on from a W3Schools example. 我从W3Schools示例中为我正在处理的FAQ页面创建了修改后的手风琴。 I am new to Javascript and I am in need of a bit of help.
我是Java语言的新手,我需要一些帮助。 I wanted to build a button that would toggle between expanding all of the panels and closing all the panels.
我想建立一个在展开所有面板和关闭所有面板之间切换的按钮。 I was able to get some help from another blog post that someone had written to create a close all panels button but now I would like to build a function that will toggle between closing all and opening all.
我可以从另一个人写的创建“关闭所有面板”按钮的博客文章中获得一些帮助,但是现在我想构建一个函数,该功能可以在“全部关闭”和“全部打开”之间切换。 I am also looking to have all of this inline so that I can embed this one page of code into another page.
我还希望将所有这些都内联,以便可以将这一页代码嵌入另一页。 I have attached the code that I have created so far.
我已经附加了到目前为止创建的代码。
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<style>
.accordion {
background-color: none;
cursor: pointer;
padding: 30px;
width: 100%;
border: #DADCE0;
border-style: solid;
border-width: 1px 0px 0px 0px;
text-align: left;
outline: none;
font-family: Google Sans, sans-serif;
font-weight: medium;
font-size: 18px;
line-height: 30px;
transition: 0.4s;
color: #1A73E8;
}
.accordion:hover {
color: #174EA6;
}
.active {
color: #174EA6;
border-top-color: #DADCE0;
border-bottom-color: #174EA6;
border-style: solid;
border-width: 1px 0px 2px 0px;
}
.accordion:after {
font-family: 'Material Icons';
content: "keyboard_arrow_down"; /*Google keyboard arrow down*/
font-weight: bold;
font-size: 24px;
float: right;
margin-left: 5px;
}
.active:after {
font-family: 'Material Icons';
content: "keyboard_arrow_up"; /*Google keyboard arrow up*/
font-weight: bold;
font-size: 24px;
float: right;
margin-left: 5px;
}
.panel {
padding: 0px 18px;
background-color: white;
max-height: 0;
overflow: hidden;
transition: max-height 0.4s ease-out;
}
.closeall {
float: right;
margin: 1% 2% 0 0;
cursor: pointer;
}
body {
font-family: Roboto Light, sans-serif;
line-height: 26px;
font-size: 16px;
color: #202124;
}
a {
color: #4285f4;
}
</style>
</head>
<body>
<button class="closeall" onclick="collapseall()">Close all</button>
<button class="accordion">Can I host my own events?</button>
<div class="panel">
<p>Of course you can!</p>
</div>
<button class="accordion">Are the events for students?</button>
<div class="panel">
<p>Yes, please see here.</p>
</div>
<button class="accordion">Are the events for teachers?</button>
<div class="panel">
<p>Yes, please see here.</p>
</div>
<button class="accordion">Are the events for teachers 2?</button>
<div class="panel">
<p>Yes, please see here 2.</p>
</div>
<script>
var acc = document.getElementsByClassName("accordion");
var i;
for (i = 0; i < acc.length; i++) {
acc[i].onclick = function() {
this.classList.toggle("active");
var panel = this.nextElementSibling;
if (panel.style.maxHeight){
panel.style.maxHeight = null;
} else {
panel.style.maxHeight = panel.scrollHeight + "px";
}
}
}
function collapseall() { //problematic part
var x = document.getElementsByClassName("panel");
var b;
for (b = 0; b < x.length; b++) {
x[b].style.maxHeight = null;
x[b].previousElementSibling.classList.remove('active');
}
}
</script>
</body>
</html>
function collapseall() {
var x = document.getElementsByClassName("accordion");
var y = 0;
var b;
for (b = 0; b < x.length; b++) {
if(x[b].classList.contains('active'))y++;
}
if(x.length==y||y==0){
for (b = 0; b < x.length; b++) {
x[b].dispatchEvent(new Event('click'));
}
}else{
for (b = 0; b < x.length; b++) {
if(x[b].classList.contains('active'))
x[b].dispatchEvent(new Event('click'));
}
}
}
Good news is you're very close to a proper solution, which I implemented here for you. 好消息是您正在接近一个适当的解决方案, 我在这里为您实施了该解决方案。 Short way to achieve that would might look like
实现该目标的捷径可能看起来像
// Single reference to all panels
// Getting them each time is heavy for the browser
var x = document.getElementsByClassName("panel");
// Indicator if we should open or close all panels
var isToggledOff = true;
Then you need two very similar functions to open or collapse all panels 然后,您需要两个非常相似的功能来打开或折叠所有面板
function collapseAll() {
for (var b = 0; b < x.length; b++) {
x[b].style.maxHeight = null;
x[b].previousElementSibling.classList.remove('active');
}
}
function expandAll() {
for (var b = 0; b < x.length; b++) {
x[b].style.maxHeight = "58px";
x[b].previousElementSibling.classList.add('active');
}
}
Last but not least you need logic that will decide if we want to open or close all panels and what to do with them in the future 最后但并非最不重要的一点是,您需要逻辑来决定我们是否要打开或关闭所有面板以及将来如何处理它们
function toggle() {
if (isToggledOff) this.expandAll();
else this.collapseAll();
isToggledOff = !isToggledOff
}
Additional things you might want to consider 您可能需要考虑的其他事项
Alternative way 替代方式
var x = Array.from(document.getElementsByClassName("panel"));
var isToggledOff = true;
function toggle() {
x.forEach(el => el
.previousElementSibling
.classList
[isToggledOff ? "add" : "remove"]('active')
)
isToggledOff = !isToggledOff
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.