Toggle divs Bootstrap like in Vanilla JS
by katalin_2003
HTML
<!--
Insipred by:
https://medium.com/dailyjs/mimicking-bootstraps-collapse-with-vanilla-javascript-b3bb389040e7
-->
<!-- data-* attributes set these buttons up as a triggers -->
<!-- Targets first div, via the data-target attribute -->
<button data-toggle="collapse" data-target=".collapse.first" data-text="Collapse">
Toggle First
</button>
<!-- Targets second div, via the data-target attribute -->
<button data-toggle="collapse" data-target=".collapse.second" data-text="Collapse">
Toggle Second
</button>
<button data-toggle="collapse" data-target=".collapse" data-text="Collapse">
Toggle All
</button>
<!-- target element to collapse/expand -->
<div class="block collapse first">
<div class="block__content">
I'm the first content!
</div>
</div>
<div class="block collapse second">
<div class="block__content">
I'm the second content!
</div>
</div>
Content after
CSS
html,
body {
font-family: sans-serif;
height: 100%;
margin: 15px;
}
*,
::after,
::before {
box-sizing: border-box;
}
.collapse {
display: block;
max-height: 0px;
overflow: hidden;
transition: max-height 0.5s cubic-bezier(0, 1, 0, 1);
}
.collapse.show {
max-height: 99em;
transition: max-height 0.5s ease-in-out;
}
.block {
margin-top: 10px;
background: #f5f5f5;
padding: 0;
}
.block__content {
border: 1px solid #ccc;
padding: 1.5em;
height: 100%;
}
JavaScript
// Handler that uses various data-* attributes to trigger
// specific actions, mimicing bootstraps attributes
// Grab all the trigger elements on the page
const triggers = Array.from(document.querySelectorAll('[data-toggle="collapse"]'));
// Listen for click events, but only on our triggers
window.addEventListener('click', (evnt) => {
const elm = evnt.target;
if (triggers.includes(elm)) {
const selector = elm.getAttribute('data-target');
collapse(selector, 'toggle');
}
}, false);
// map our commands to the classList methods
const fnmap = {
'toggle': 'toggle', // toggle
'show': 'add', // add
'hide': 'remove' // remove
};
function collapse(selector, command) {
const targets = Array.from(document.querySelectorAll(selector));
targets.forEach(target => {
target.classList[fnmap[command]]('show'); // show
console.table(target.classList);
});
}