Reputation: 55
I have accordion block. When you click on an inactive item, it becomes active. The active class is removed from the previous item. It all works.
But now I needed to make it so that when you click on the active item again, it becomes inactive again.
I also have a function so that hiding / opening items happens without jerks. But it doesn't work with the current JS code:
function setHeight() {
if (content.offsetHeight) {
content.style.height = 0;
} else {
content.style.height = accordText.offsetHeight + 'px';
};
};
How can I do that?
const accordItems = document.querySelectorAll('.accordion__item');
accordItems.forEach(item => {
const accordText = item.querySelector('.accordion__text');
const content = item.querySelector('.accordion__content');
item.addEventListener('click', (event) => {
accordItems.forEach(item => {
item.classList.remove('active');
});
item.classList.add('active');
});
});
@import url("https://fonts.googleapis.com/css2?family=Lora&display=swap");
@import url("https://fonts.googleapis.com/css2?family=Roboto&display=swap");
body {
margin: 0;
padding: 0;
box-sizing: border-box;
color: #1f1f1f;
background: #f2f2f2; }
html {
font-size: 62.5%; }
h5 {
margin: 0; }
p {
margin: 0; }
.container {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: auto;
max-width: 140rem; }
.section-accordion {
display: flex;
align-items: center;
max-width: 134rem;
margin: auto; }
.accordion-image {
width: 630px;
height: 450px;
background: url("https://eternel.maitreart.com/wp-content/uploads/2021/07/creat-home-1.jpg");
background-repeat: no-repeat;
background-size: cover; }
.accordion {
width: 63rem;
height: auto;
margin-left: 8rem; }
.accordion__item {
border-top: 1px solid #a8a6a4;
overflow: hidden;
transition: height .5s;
padding-bottom: 1rem; }
.accordion__item.active {
height: 100%; }
.accordion__item:last-child {
border-bottom: 1px solid #a8a6a4; }
.accordion__header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 2rem 1rem 1rem 1rem;
cursor: pointer; }
.accordion__title {
font-family: 'Lora';
font-size: 2.4rem;
line-height: 1.2;
font-weight: 400;
text-transform: uppercase; }
.accordion__icon {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
width: 2rem;
height: 2rem;
transition: transform .5s ease; }
.accordion__icon span:first-child {
transform: rotate(90deg) translateX(1px);
width: 1.4rem;
height: .1rem;
background: currentColor; }
.accordion__icon span {
display: block;
width: 1.4rem;
height: .1rem;
background: currentColor;
cursor: pointer; }
.accordion__content {
font-family: 'Roboto', sans-serif;
font-size: 1.6rem;
line-height: 1.62;
font-weight: 400;
padding: 0 1rem 0 1rem;
height: 0;
overflow: hidden;
transition: height .5s; }
.accordion__item.active > .accordion__header .accordion__icon {
transform: rotate(45deg); }
.accordion__item.active > .accordion__content {
margin-bottom: 1.2rem;
height: 100%; }
<div class="container">
<section class="section-accordion">
<div class="accordion-image"></div>
<div class="accordion">
<div class="accordion__item active">
<div class="accordion__header">
<h5 class="accordion__title">Visual direction</h5>
<div class="accordion__icon">
<span></span>
<span></span>
</div>
</div>
<div class="accordion__content">
<p class="accordion__text">Carried nothing on am warrant towards. Polite in of in oh needed itself silent course.
Assistance travelling so especially do prosperous appearance mr no celebrated.
Wanted easily in my called formed suffer. Songs hoped sense.
</p>
</div>
</div>
<div class="accordion__item">
<div class="accordion__header">
<h5 class="accordion__title">Event production</h5>
<div class="accordion__icon">
<span></span>
<span></span>
</div>
</div>
<div class="accordion__content">
<p class="accordion__text">Carried nothing on am warrant towards. Polite in of in oh needed itself silent course.
Assistance travelling so especially do prosperous appearance mr no celebrated.
Wanted easily in my called formed suffer. Songs hoped sense.
</p>
</div>
</div>
<div class="accordion__item">
<div class="accordion__header">
<h5 class="accordion__title">Brand creation</h5>
<div class="accordion__icon">
<span></span>
<span></span>
</div>
</div>
<div class="accordion__content">
<p class="accordion__text">Carried nothing on am warrant towards. Polite in of in oh needed itself silent course.
Assistance travelling so especially do prosperous appearance mr no celebrated.
Wanted easily in my called formed suffer. Songs hoped sense.
</p>
</div>
</div>
<div class="accordion__item">
<div class="accordion__header">
<h5 class="accordion__title">Design concept</h5>
<div class="accordion__icon">
<span></span>
<span></span>
</div>
</div>
<div class="accordion__content">
<p class="accordion__text">Carried nothing on am warrant towards. Polite in of in oh needed itself silent course.
Assistance travelling so especially do prosperous appearance mr no celebrated.
Wanted easily in my called formed suffer. Songs hoped sense.
</p>
</div>
</div>
</div>
</div>
</section>
</div>
Upvotes: 0
Views: 788
Reputation: 505
Instead of adding and removing class you can use a shorthand syntax toggle
it makes things easier.
It remove the class if the class is present vice versa
Here's the code for it
item.classList.toggle('active')
const accordItems = document.querySelectorAll('.accordion__item');
accordItems.forEach(item => {
const accordText = item.querySelector('.accordion__text');
const content = item.querySelector('.accordion__content');
item.addEventListener('click', (event) => {
accordItems.forEach(item => {
item.classList.toggle('active');
});
item.classList.add('active');
});
});
Upvotes: 0
Reputation: 4282
Can you do something like this?
accordItems.forEach(item => {
const accordText = item.querySelector('.accordion__text');
const content = item.querySelector('.accordion__content');
item.addEventListener('click', (event) => {
const wasActive = item.classList.contains('active');
accordItems.forEach(item => {
item.classList.remove('active');
});
if (!wasActive) {
item.classList.add('active');
}
});
});
This makes a clicked item active only if it wasn't active when the click occurred. Toggling is another option, if you are okay with more than one item being active at the same time:
accordItems.forEach(item => {
const accordText = item.querySelector('.accordion__text');
const content = item.querySelector('.accordion__content');
item.addEventListener('click', (event) => {
item.classList.toggle('active');
});
});
Upvotes: 1