Created
July 16, 2025 17:35
-
-
Save undfine/60d2b62fb5320b77836975618bdf0190 to your computer and use it in GitHub Desktop.
Create accordion from sections
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| document.addEventListener('DOMContentLoaded', () => { | |
| /** | |
| * Sets up accordion functionality within a given container element. | |
| * Finds sections based on a selector, wraps them and their subsequent content, | |
| * and adds toggle functionality. | |
| * @param {HTMLElement} container The HTML element acting as the accordion container. | |
| * @param {string} sectionSelector The CSS selector for the elements that will act as section titles (e.g., 'h2', 'h3', '.my-title-class'). | |
| */ | |
| function setupAccordion(container, sectionSelector = 'h2') { // Default to 'h2' | |
| // Query sections within this specific container using the provided selector | |
| const sections = container.querySelectorAll(sectionSelector); | |
| sections.forEach(section => { | |
| // Create a slug from the section's text content for use as an ID | |
| const sectionText = section.textContent; | |
| const idSlug = sectionText | |
| .toLowerCase() | |
| .replace(/[^\w\s-]/g, '') | |
| .replace(/[\s_-]+/g, '-') | |
| .replace(/^-+|-+$/g, ''); | |
| // Add the new class to the section title | |
| section.classList.add('accordion-title'); | |
| // Create the main accordion item container | |
| const accordionItem = document.createElement('div'); | |
| accordionItem.classList.add('accordion-item'); | |
| // Create the accordion content div | |
| const accordionContent = document.createElement('div'); | |
| accordionContent.classList.add('accordion-content'); | |
| accordionContent.hidden = true; // Initial state: content is hidden by default | |
| accordionContent.id = `accordion-content-${idSlug}`; // Set the ID for the content | |
| // Move sibling elements into the accordion content until the next section title or end of document | |
| let currentElement = section.nextElementSibling; | |
| while (currentElement && !currentElement.matches(sectionSelector)) { | |
| accordionContent.appendChild(currentElement); | |
| currentElement = section.nextElementSibling; // Get the *new* next sibling | |
| } | |
| // Insert the accordion item right before the section title in its original parent | |
| section.parentNode.insertBefore(accordionItem, section); | |
| // Then, move the section title and the accordionContent into the accordionItem | |
| accordionItem.appendChild(section); | |
| accordionItem.appendChild(accordionContent); | |
| // Add event listener to the section title for toggling | |
| section.addEventListener('click', () => { | |
| const isActive = accordionItem.classList.toggle('active'); | |
| // Toggle ARIA attributes for accessibility | |
| section.setAttribute('aria-expanded', isActive); | |
| accordionContent.setAttribute('aria-hidden', !isActive); | |
| accordionContent.hidden = !isActive; | |
| }); | |
| // Set initial ARIA attributes for accessibility | |
| section.setAttribute('role', 'button'); | |
| section.setAttribute('tabindex', '0'); | |
| section.setAttribute('aria-controls', accordionContent.id); | |
| accordionContent.setAttribute('aria-hidden', 'true'); | |
| }); | |
| } | |
| // --- Main Execution --- | |
| // Find all containers that should be accordions | |
| const accordionContainers = document.querySelectorAll('.make-accordion'); | |
| // Setup each container as an accordion | |
| accordionContainers.forEach(container => { | |
| // You can now pass the desired selector for each container | |
| // If not provided, it will default to 'h2' as defined in the function signature. | |
| // Example: setupAccordion(container, 'h3'); // If you want to use h3s as titles in this container | |
| setupAccordion(container); // Uses default 'h2' for all .make-accordion containers | |
| }); | |
| // Example of setting up an accordion with h3s in a specific container: | |
| // If you had a container like <div id="my-h3-accordion" class="make-accordion"> | |
| // const h3AccordionContainer = document.getElementById('my-h3-accordion'); | |
| // if (h3AccordionContainer) { | |
| // setupAccordion(h3AccordionContainer, 'h3'); | |
| // } | |
| }); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment