Data Toggle Expand β
dataToggleExpand.js β
js
/**
* @method collapseElement
* @param {HTMLElement} element
*/
function collapseElement(element) {
/**
* Get the height of the element's inner content,
* regardless of its actual size
*/
const elementHeight = element.scrollHeight;
// Temporarily disable all css transitions
const elementTransition = element.style.transition;
element.style.transition = "";
/**
* On the next frame (as soon as the previous style change has taken effect),
* explicitly set the element's height to its current pixel height,
* so we aren't transitioning out of 'auto'
*/
requestAnimationFrame(() => {
element.style.height = `${elementHeight}px`;
element.style.transition = elementTransition;
/**
* On the next frame (as soon as the previous style change has taken effect),
* have the element transition to height: 0
*/
requestAnimationFrame(() => {
element.style.height = 0 + "px";
});
});
// Mark the element as 'currently not expanded'
element.classList.remove("expanded");
}
/**
* @method expandElement
* @param {HTMLElement} element
*/
function expandElement(element) {
/**
* Get the height of the element's inner content,
* regardless of its actual size
*/
const elementHeight = element.scrollHeight;
// Have the element transition to the height of its inner content
element.style.height = `${elementHeight}px`;
// When the next css transition finishes (which should be the one we just triggered)
element.addEventListener("transitionend", function (e) {
// Remove this event listener so it only gets triggered once
element.removeEventListener("transitionend", arguments.callee);
/**
* Remove 'height' from the element's inline styles,
* so it can return to its initial value
*/
element.style.height = null;
});
// Mark the element as 'currently expanded'
element.classList.add("expanded");
}
const dataToggles = document.querySelectorAll('[data-toggle="expand"]');
Array.prototype.forEach.call(dataToggles, dataToggle => {
const targetId = dataToggle.getAttribute("data-target");
const targetElement = document.querySelector(targetId);
const isCollapsed = !targetElement.classList.contains("expanded");
if (isCollapsed) {
collapseElement(targetElement);
}
dataToggle.addEventListener("click", () => {
const isExpanded = targetElement.classList.contains("expanded");
if (isExpanded) {
collapseElement(targetElement);
// A11Y
dataToggle.setAttribute("aria-expanded", "false");
} else {
expandElement(targetElement);
// A11Y
dataToggle.setAttribute("aria-expanded", "true");
}
});
});