element
this.content = el.querySelector(".content-area");
// // Store the animation object (so we can cancel it if needed)
this.animation = null;
// // Store if the element is closing
this.isClosing = false;
// // Store if the element is expanding
this.isExpanding = false;
// // Detect user clicks on the summary element
this.summary.addEventListener("click", (e) => this.onClick(e));
this.el.addEventListener("close", () => this.shrink());
}
onClick(e) {
if (e.target.tagName.toLowerCase() !== 'a') {
e.preventDefault();
}
// Stop default behaviour from the browser
// Add an overflow on the
to avoid content overflowing
this.el.style.overflow = "hidden";
// Check if the element is being closed or is already closed
if (this.isClosing || !this.el.open) {
this.open();
// Check if the element is being opened or is already open
} else if (this.isExpanding || this.el.open) {
this.shrink();
}
}
getTransitionDuration(openOrClose) {
if ('open' === openOrClose && this.el.hasAttribute('data-transition-duration-open-in-ms')) {
return parseInt(this.el.getAttribute('data-transition-duration-open-in-ms'), 10);
}
if ('close' === openOrClose && this.el.hasAttribute('data-transition-duration-close-in-ms')) {
return parseInt(this.el.getAttribute('data-transition-duration-close-in-ms'), 10);
}
if (this.el.hasAttribute('data-transition-duration-in-ms')) {
return parseInt(this.el.getAttribute('data-transition-duration-in-ms'), 10);
}
return 200;
}
shrink() {
// Set the element as "being closed"
this.isClosing = true;
// Store the current height of the element
const startHeight = `${this.el.offsetHeight}px`;
// Calculate the height of the summary
const endHeight = `${this.summary.offsetHeight}px`;
// If there is already an animation running
if (this.animation) {
// Cancel the current animation
this.animation.cancel();
}
// Start a WAAPI animation
this.animation = this.el.animate(
{
// Set the keyframes from the startHeight to endHeight
height: [startHeight, endHeight],
},
{
duration: this.getTransitionDuration('close'),
easing: "linear",
}
)
;
// When the animation is complete, call onAnimationFinish()
this.animation.onfinish = () => this.onAnimationFinish(false);
// If the animation is cancelled, isClosing variable is set to false
this.animation.oncancel = () => (this.isClosing = false);
this.el.classList.add("closing");
this.el.classList.toggle('accordion-open');
}
open() {
// Apply a fixed height on the element
this.el.style.height = `auto`;
// Force the [open] attribute on the details element
this.el.open = true;
if (this.container) {
this.closeAllButThis();
}
// Wait for the next frame to call the expand function
window.requestAnimationFrame(() => this.expand());
}
closeAllButThis() {
// Triggering "close" event for any attached listeners on the