I've been working on a solution that allows a set of buttons to reveal divs that slide down from above on-click. I needed each button to toggle an active state for itself, but also if the user were to click on one button, reveal a div, and then go on to click another button, that the initially revealed div transition back up and dissapear while the new one appears.
When all the buttons are on one line, my solution works relatively well. But when there are buttons below some of the hidden divs, suddenly the divs those buttons trigger appear from below instead of dropping down from above... IF one of the buttons above has an active state... If not, business as usual.
Appologies if this is confusing, please see my fiddle : https://jsfiddle.net/maesj_/qdk4z1vm/26/
My solution is an adaptation of a demo that I found on css-tricks adressing a similar kind of situation, but in my case having mutliple buttons has added a bit more complexity to the mix and I'm wondering if anyone has any ideas on how I might improve my code.
Any thoughts are much appreciated!
HTML
<button class="dyn-gallery-btn" type="button"> one </button>
<button class="dyn-gallery-btn" type="button"> two </button>
<div class="dyn-slide"> one text
</div>
<div class="dyn-slide"> two text
</div>
<button class="dyn-gallery-btn" type="button"> three </button>
<button class="dyn-gallery-btn" type="button"> four </button>
<div class="dyn-slide"> three text
</div>
<div class="dyn-slide"> four text
</div>
CSS
.dyn-slide {
background: red;
transition: height .5s ease-in-out;
height: 0;
overflow: hidden;
}
.dyn-slide.active {
height: auto;
overflow: hidden;
}
.dyn-slide:not(.active) {
height: 0;
overflow: hidden;
}
JS
const slides = document.querySelectorAll('.dyn-slide')
const buttons = document.querySelectorAll('.dyn-gallery-btn')
buttons.forEach((button, i) => {
button.addEventListener('click', () => {
const slide = slides[i]
const wasActive = slide.classList.contains('active')
slides.forEach(slide => {
slide.classList.remove('active')
slide.style.height = 0;
})
if (!wasActive) {
slide.classList.add('active')
slide.style.height = 'auto';
var height = slide.clientHeight + 'px';
slide.style.height = '0px';
setTimeout(function () {
slide.style.height = height;
}, 0);
} else {
var height = slide.clientHeight + 'px';
slide.style.height = '0px';
setTimeout(function () {
slide.style.height = 0;
}, 0);
}
})
})