Accordion
Simple Accordion in Vanilla JS
by mrjordy
HTML
<div class="accordionMenuBar">
<div class="accordionMenu1 closeAll"><button onclick="closeallFunction()">close all</button></div>
<div class="accordionMenu2 expandAll">expand all</div>
<div class="accordionMenu3 personType1">person type 1</div>
<div class="accordionMenu4 personType2">person type 2</div>
<div class="accordionMenu5 personType3">person type 3</div>
</div>
<div class="accordionTrigger">H2 thing 1</div>
<div class="accordionPane show">
<p>text</p>
</div>
<div class="accordionTrigger">H2 thing 2</div>
<div class="accordionPane show">
<p>text</p>
</div>
<div class="accordionTrigger">H2 thing 3</div>
<div class="accordionPane show">
<p>text</p>
</div>
CSS
/* Style the buttons that are used to open and close the accordion panel */
.accordionTrigger {
background-color: #eee;
color: #444;
cursor: pointer;
padding: 18px;
width: 100%;
text-align: left;
border: none;
outline: none;
transition: 0.4s;
}
/* Add a background color to the button if it is clicked on (add the .active class with JS), and when you move the mouse over it (hover) */
.accordionTrigger.active,
.accordionTrigger:hover {
background-color: #ddd;
}
.accordionPane {
padding: 0 18px;
background-color: white;
max-height: 0;
overflow: hidden;
transition: 0.6s ease-in-out;
opacity: 0;
}
/* The "show" class is added to the accordion panel when the user clicks on one of the buttons. This will show the panel content */
.accordionPane.show {
opacity: 1;
max-height: 500px;
}
JavaScript
// Event delegation
document.addEventListener("click", delegate(accFilter, accHandler));
// close all
function closeallFunction() {
var element = document.getElementByClass("accordionPane");
element.classList.add("show");
}
// Common helper for event delegation.
function delegate(criteria, listener) {
return function(e) {
var el = e.target;
do {
if (!criteria(el)) {
continue;
}
e.delegateTarget = el;
listener.call(this, e);
return;
} while ((el = el.parentNode));
};
}
// Custom filter to check for required DOM elements
function accFilter(elem) {
return (elem instanceof HTMLElement) && elem.matches(".accordionTrigger");
}
// Custom event handler function
function accHandler(e) {
var acc = e.delegateTarget;
acc.classList.toggle("active");
acc.nextElementSibling.classList.toggle("show");
var otherAccordions = getSiblings(acc.nextElementSibling, '.accordionPane');
otherAccordions.forEach(function(otherAcc) {
otherAcc.classList.remove('show');
otherAcc.previousElementSibling.classList.remove("active");
})
}