Как скрывать другие спойлеры, когда открываешь один?
Я могу открывать и закрывать каждый спойлер независимо от других. Как сделать чтобы одновременно активным был только один спойлер? Иными словами, как изменить мой код для логики аккордеона?
const spoiler = document.querySelectorAll('.title');
spoiler.forEach(function(index) {
index.addEventListener('click', function() {
this.classList.toggle('active');
let content = this.nextElementSibling;
if (content.style.maxHeight) {
content.style.maxHeight = null;
}
else
{
content.style.maxHeight = content.scrollHeight + 'px';
}
});
});
body
{
font-family: 'Arial', sans-serif;
margin: 10px;
}
*,
*:before,
*:after
{
box-sizing: border-box;
padding: 0;
margin: 0;
}
.container
{
max-width: 480px;
margin: 0 auto;
border: 1px solid #e5e5e5;
background-color: #f5f5f5;
box-shadow: rgba(100, 100, 110, 0.25) 0px 5px 30px 0px;
border-radius: 5px;
overflow: hidden;
}
.title
{
cursor: pointer;
position: relative;
user-select: none;
padding: 10px 20px;
font-size: 14px;
}
.item + .item {
border-top: 1px solid #e5e5e5;
}
.title.active {
font-weight: bold;
background-color: white;
}
.title:before,
.title:after {
content: '';
position: absolute;
height: 1px;
width: 7px;
top: 50%;
transform: translate(0, -50%);
background: #000;
display: block;
}
.title:before
{
transform: rotate(45deg);
right: 24.5px;
}
.title:after
{
transform: rotate(-45deg);
right: 20px;
}
.content
{
opacity: 0;
user-select: none;
padding-top: 0;
overflow: hidden;
max-height: 0;
transition: .3s max-height;
background-color: white;
}
.content p {
padding: 10px 20px;
font-size: 14px;
}
.title.active ~ .content
{
opacity: 1;
}
.title.active:before
{
transform: rotate(-45deg);
height: 2px;
}
.title.active:after
{
transform: rotate(45deg);
height: 2px;
}
<div class="container">
<div class="item">
<div class="title">
<p>Title</p>
</div>
<div class="content">
<p>Lorem ipsum dolor, sit amet, consectetur adipisicing elit. Exercitationem suscipit minus unde accusantium minima voluptates quisquam. Perspiciatis, officiis excepturi aliquid exercitationem culpa in, vero quisquam.</p>
</div>
</div>
<div class="item">
<div class="title">
<p>Title</p>
</div>
<div class="content">
<p>Lorem ipsum, dolor sit amet, consectetur adipisicing elit. Necessitatibus, atque ratione maxime aspernatur a. Recusandae minus sunt blanditiis voluptate cum velit ipsum non placeat quibusdam.</p>
</div>
</div>
<div class="item">
<div class="title">
<p>Title</p>
</div>
<div class="content">
<p>Lorem, ipsum dolor sit amet, consectetur adipisicing elit. Tempore iure consequuntur nostrum quibusdam odit, deserunt aliquid ratione maiores eos consectetur natus omnis dolorum mollitia totam.</p>
</div>
</div>
</div>
Ответы (2 шт):
Автор решения: UModeL
→ Ссылка
Чтобы добиться нужного поведения блоков, достаточно осуществлять их перебор с удалением класса .active, а у того, который в данный момент был нажат - переключать класс:
const spoiler = document.querySelectorAll('.title');
spoiler.forEach(function(index) {
index.addEventListener('click', function() {
spoiler.forEach((el) => {
let content = el.nextElementSibling;
if (el != this) {
content.style.maxHeight = null;
el.classList.remove('active');
} else {
content.style.maxHeight = content.style.maxHeight ? null : content.scrollHeight + 'px';
this.classList.toggle('active');
}
});
});
});
*,
*::before,
*::after {
box-sizing: border-box;
padding: 0;
margin: 0;
}
body {
font-family: 'Arial', sans-serif;
margin: 10px;
}
.container {
max-width: 480px;
margin: 0 auto;
border: 1px solid #e5e5e5;
background-color: #f5f5f5;
box-shadow: rgba(100, 100, 110, 0.25) 0px 5px 30px 0px;
border-radius: 5px;
overflow: hidden;
}
.item+.item {
border-top: 1px solid #e5e5e5;
}
.title {
cursor: pointer;
position: relative;
user-select: none;
padding: 10px 20px;
font-size: 14px;
}
.title::before,
.title::after {
content: '';
position: absolute;
height: 1px;
width: 7px;
top: 50%;
transform: translate(0, -50%);
background: #000;
display: block;
}
.title::before {
transform: rotate(45deg);
right: 24.5px;
}
.title::after {
transform: rotate(-45deg);
right: 20px;
}
.title.active {
font-weight: bold;
background-color: white;
}
.title.active::before {
transform: rotate(-45deg);
height: 2px;
}
.title.active::after {
transform: rotate(45deg);
height: 2px;
}
.content {
opacity: 0;
user-select: none;
padding-top: 0;
overflow: hidden;
max-height: 0;
transition: 0.3s max-height;
background-color: white;
}
.title.active~.content {
opacity: 1;
}
.content p {
padding: 10px 20px;
font-size: 14px;
}
<div class="container">
<div class="item">
<div class="title">
<p>Title</p>
</div>
<div class="content">
<p>Lorem ipsum dolor, sit amet, consectetur adipisicing elit. Exercitationem suscipit minus unde accusantium minima voluptates quisquam. Perspiciatis, officiis excepturi aliquid exercitationem culpa in, vero quisquam.</p>
</div>
</div>
<div class="item">
<div class="title">
<p>Title</p>
</div>
<div class="content">
<p>Lorem ipsum, dolor sit amet, consectetur adipisicing elit. Necessitatibus, atque ratione maxime aspernatur a. Recusandae minus sunt blanditiis voluptate cum velit ipsum non placeat quibusdam.</p>
</div>
</div>
<div class="item">
<div class="title">
<p>Title</p>
</div>
<div class="content">
<p>Lorem, ipsum dolor sit amet, consectetur adipisicing elit. Tempore iure consequuntur nostrum quibusdam odit, deserunt aliquid ratione maiores eos consectetur natus omnis dolorum mollitia totam.</p>
</div>
</div>
</div>
Автор решения: Andrey Semykin
→ Ссылка
Ты вот такой результат хотел получить?
const spoilers = document.querySelectorAll('.title');
const container = document.querySelector('.container');
container.addEventListener('click', function(e){
const target = e.target.closest('.title');
if (target.classList.contains('active')){
target.classList.remove('active');
let content = target.nextElementSibling;
content.style.maxHeight = null;
}else{
spoilers.forEach(function(splr) {
splr.classList.remove('active');
let content = splr.nextElementSibling;
content.style.maxHeight = null;
});
target.classList.add('active');
let content = target.nextElementSibling;
if (content.style.maxHeight) {
content.style.maxHeight = null;
}
else
{
content.style.maxHeight = content.scrollHeight + 'px';
}
}
})
body
{
font-family: 'Arial', sans-serif;
margin: 10px;
}
*,
*:before,
*:after
{
box-sizing: border-box;
padding: 0;
margin: 0;
}
.container
{
max-width: 480px;
margin: 0 auto;
border: 1px solid #e5e5e5;
background-color: #f5f5f5;
box-shadow: rgba(100, 100, 110, 0.25) 0px 5px 30px 0px;
border-radius: 5px;
overflow: hidden;
}
.title
{
cursor: pointer;
position: relative;
user-select: none;
padding: 10px 20px;
font-size: 14px;
}
.item + .item {
border-top: 1px solid #e5e5e5;
}
.title.active {
font-weight: bold;
background-color: white;
}
.title:before,
.title:after {
content: '';
position: absolute;
height: 1px;
width: 7px;
top: 50%;
transform: translate(0, -50%);
background: #000;
display: block;
}
.title:before
{
transform: rotate(45deg);
right: 24.5px;
}
.title:after
{
transform: rotate(-45deg);
right: 20px;
}
.content
{
opacity: 0;
user-select: none;
padding-top: 0;
overflow: hidden;
max-height: 0;
transition: .3s max-height;
background-color: white;
}
.content p {
padding: 10px 20px;
font-size: 14px;
}
.title.active ~ .content
{
opacity: 1;
}
.title.active:before
{
transform: rotate(-45deg);
height: 2px;
}
.title.active:after
{
transform: rotate(45deg);
height: 2px;
}
<div class="container">
<div class="item">
<div class="title">
<p>Title</p>
</div>
<div class="content">
<p>Lorem ipsum dolor, sit amet, consectetur adipisicing elit. Exercitationem suscipit minus unde accusantium minima voluptates quisquam. Perspiciatis, officiis excepturi aliquid exercitationem culpa in, vero quisquam.</p>
</div>
</div>
<div class="item">
<div class="title">
<p>Title</p>
</div>
<div class="content">
<p>Lorem ipsum, dolor sit amet, consectetur adipisicing elit. Necessitatibus, atque ratione maxime aspernatur a. Recusandae minus sunt blanditiis voluptate cum velit ipsum non placeat quibusdam.</p>
</div>
</div>
<div class="item">
<div class="title">
<p>Title</p>
</div>
<div class="content">
<p>Lorem, ipsum dolor sit amet, consectetur adipisicing elit. Tempore iure consequuntur nostrum quibusdam odit, deserunt aliquid ratione maiores eos consectetur natus omnis dolorum mollitia totam.</p>
</div>
</div>
</div>