'How to remove the class when the element is clicked again JS
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>
Solution 1:[1]
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');
});
});
Solution 2:[2]
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');
});
});
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | twharmon |
| Solution 2 | Icekid |
