如何让手风琴一次只有一个可折叠?
How to Make Accordion Have Only One Collapsible at a Time?
我正在使用 W3Schools (https://www.w3schools.com/howto/tryit.asp?filename=tryhow_js_accordion_symbol) 中的这段代码,但我一次只需要打开一个手风琴。正如您从示例中看到的那样,一次可以打开无限量的手风琴。
我认为只要在 javascript 中添加另一个 if 条件就可以解决这个问题,但我对 JavaScript 不太熟悉,无法弄清楚。
有人可以帮我吗?
HTML:
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<h2>Accordion with symbols</h2>
<p>In this example we have added a "plus" sign to each button. When the user clicks on the button, the "plus" sign is replaced with a "minus" sign.</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>
</body>
</html>
CSS:
.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;
}
.accordion:after {
content: '[=11=]2B';
color: #777;
font-weight: bold;
float: right;
margin-left: 5px;
}
.active:after {
content: "12";
}
.panel {
padding: 0 18px;
background-color: white;
max-height: 0;
overflow: hidden;
transition: max-height 0.2s ease-out;
}
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";
}
});
}
在打开所需窗格的代码中,插入(就在打开代码之前)遍历所有面板并关闭它们的循环。
var acc = document.querySelectorAll(".accordion");
var i;
for (i = 0; i < acc.length; i++) {
acc[i].addEventListener("click", function() {
// Loop over all the panels an close each one
document.querySelectorAll(".panel").forEach(function(panel){
panel.style.maxHeight = "0";
panel.previousElementSibling.classList.remove("active");
});
// Then show the clicked panel
this.classList.toggle("active");
var panel = this.nextElementSibling;
panel.style.maxHeight = panel.scrollHeight + "px";
});
}
.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;
}
.accordion:after {
content: '[=11=]2B';
color: #777;
font-weight: bold;
float: right;
margin-left: 5px;
}
.active:after {
content: "12";
}
.panel {
padding: 0 18px;
background-color: white;
max-height: 0;
overflow: hidden;
transition: max-height 0.2s ease-out;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<h2>Accordion with symbols</h2>
<p>In this example we have added a "plus" sign to each button. When the user clicks on the button, the "plus" sign is replaced with a "minus" sign.</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>
</body>
</html>
话虽如此,众所周知,W3School 是一个糟糕的资源,因为它经常包含不完整、过时或完全错误的信息。举个例子, .getElementsByClasName()
is a 25+ year old out-dated API that really should not be used in 2019. Use .querySelectorAll()
代替。此外,强烈建议不要使用内联样式和元素的 .style
属性。相反,使用预制的 CSS classes.
这是执行此操作的现代方法(请注意,已添加新的 div
来包裹整个手风琴,并且每个 button
的 class 已更改为 section
):
// Set up the click event on the accordion itself
// When a panel is clicked, that event will bubble up
// to the accordion and can be handled there.
document.querySelector(".accordion").addEventListener("click", function(event){
// Check to see if the clicked panel was the currently open one.
let alreadyActive = event.target.classList.contains("active");
// Loop over all the panels an close each one
document.querySelectorAll(".panel").forEach(function(panel){
panel.style.maxHeight = "0";
panel.previousElementSibling.classList.remove("active");
});
// If the clicked panel wasn't the already active one go ahead
// and open the clicked panel. Otherwise, do nothing and leave
// all the panels closed.
if(!alreadyActive){
// Then show the clicked panel which is accessible as event.target
event.target.classList.add("active");
var panel = event.target.nextElementSibling;
panel.style.maxHeight = panel.scrollHeight + "px";
}
});
.section {
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, .section:hover {
background-color: #ccc;
}
.section:after {
content: '[=14=]2B';
color: #777;
font-weight: bold;
float: right;
margin-left: 5px;
}
.section.active:after {
content: "12";
}
.panel {
padding: 0 18px;
background-color: white;
max-height: 0;
overflow: hidden;
transition: max-height 0.2s ease-out;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<h2>Accordion with symbols</h2>
<p>In this example we have added a "plus" sign to each button. When the user clicks on the button, the "plus" sign is replaced with a "minus" sign.</p>
<div class="accordion">
<button class="section">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="section">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="section">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>
</div>
</body>
</html>
我正在使用 W3Schools (https://www.w3schools.com/howto/tryit.asp?filename=tryhow_js_accordion_symbol) 中的这段代码,但我一次只需要打开一个手风琴。正如您从示例中看到的那样,一次可以打开无限量的手风琴。
我认为只要在 javascript 中添加另一个 if 条件就可以解决这个问题,但我对 JavaScript 不太熟悉,无法弄清楚。
有人可以帮我吗?
HTML:
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<h2>Accordion with symbols</h2>
<p>In this example we have added a "plus" sign to each button. When the user clicks on the button, the "plus" sign is replaced with a "minus" sign.</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>
</body>
</html>
CSS:
.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;
}
.accordion:after {
content: '[=11=]2B';
color: #777;
font-weight: bold;
float: right;
margin-left: 5px;
}
.active:after {
content: "12";
}
.panel {
padding: 0 18px;
background-color: white;
max-height: 0;
overflow: hidden;
transition: max-height 0.2s ease-out;
}
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";
}
});
}
在打开所需窗格的代码中,插入(就在打开代码之前)遍历所有面板并关闭它们的循环。
var acc = document.querySelectorAll(".accordion");
var i;
for (i = 0; i < acc.length; i++) {
acc[i].addEventListener("click", function() {
// Loop over all the panels an close each one
document.querySelectorAll(".panel").forEach(function(panel){
panel.style.maxHeight = "0";
panel.previousElementSibling.classList.remove("active");
});
// Then show the clicked panel
this.classList.toggle("active");
var panel = this.nextElementSibling;
panel.style.maxHeight = panel.scrollHeight + "px";
});
}
.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;
}
.accordion:after {
content: '[=11=]2B';
color: #777;
font-weight: bold;
float: right;
margin-left: 5px;
}
.active:after {
content: "12";
}
.panel {
padding: 0 18px;
background-color: white;
max-height: 0;
overflow: hidden;
transition: max-height 0.2s ease-out;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<h2>Accordion with symbols</h2>
<p>In this example we have added a "plus" sign to each button. When the user clicks on the button, the "plus" sign is replaced with a "minus" sign.</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>
</body>
</html>
话虽如此,众所周知,W3School 是一个糟糕的资源,因为它经常包含不完整、过时或完全错误的信息。举个例子, .getElementsByClasName()
is a 25+ year old out-dated API that really should not be used in 2019. Use .querySelectorAll()
代替。此外,强烈建议不要使用内联样式和元素的 .style
属性。相反,使用预制的 CSS classes.
这是执行此操作的现代方法(请注意,已添加新的 div
来包裹整个手风琴,并且每个 button
的 class 已更改为 section
):
// Set up the click event on the accordion itself
// When a panel is clicked, that event will bubble up
// to the accordion and can be handled there.
document.querySelector(".accordion").addEventListener("click", function(event){
// Check to see if the clicked panel was the currently open one.
let alreadyActive = event.target.classList.contains("active");
// Loop over all the panels an close each one
document.querySelectorAll(".panel").forEach(function(panel){
panel.style.maxHeight = "0";
panel.previousElementSibling.classList.remove("active");
});
// If the clicked panel wasn't the already active one go ahead
// and open the clicked panel. Otherwise, do nothing and leave
// all the panels closed.
if(!alreadyActive){
// Then show the clicked panel which is accessible as event.target
event.target.classList.add("active");
var panel = event.target.nextElementSibling;
panel.style.maxHeight = panel.scrollHeight + "px";
}
});
.section {
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, .section:hover {
background-color: #ccc;
}
.section:after {
content: '[=14=]2B';
color: #777;
font-weight: bold;
float: right;
margin-left: 5px;
}
.section.active:after {
content: "12";
}
.panel {
padding: 0 18px;
background-color: white;
max-height: 0;
overflow: hidden;
transition: max-height 0.2s ease-out;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<h2>Accordion with symbols</h2>
<p>In this example we have added a "plus" sign to each button. When the user clicks on the button, the "plus" sign is replaced with a "minus" sign.</p>
<div class="accordion">
<button class="section">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="section">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="section">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>
</div>
</body>
</html>