Accordion

The forEach() method of Array instances executes a provided function once for each array element.

MDN: Array.prototype.forEach()

The read-only classList property of the Element interface contains a live DOMTokenList collection representing the class attribute of the element. This can then be used to manipulate the class list.

MDN: Element: classList property

The getAttribute() method of the Element interface returns the value of a specified attribute on the element.

If the given attribute does not exist, the value returned will be null.

Element: getAttribute() method

The setAttribute() method of the Element interface sets the value of an attribute on the specified element. If the attribute already exists, the value is updated; otherwise a new attribute is added with the specified name and value.

Element: setAttribute() method

The HTMLElement property hidden reflects the value of the element's hidden attribute.

HTMLElement: hidden property

The HTML

							
								<div class="accordion">
								    <div class="accordion_item">
								        <h3>
								            <button type="button" class="accordion_trigger button" aria-expanded="false">
								                <span>Array.prototype.forEach()</span>
								                <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" class="ionicon" viewBox="0 0 512 512"><path fill="none" stroke="" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" d="M256 112v288M400 256H112"/></svg>
								            </button>
								        </h3>
								        <div class="accordion_panel" role="region">
								            <p>The forEach() method of Array instances executes a provided function once for each array element.</p>
								            <p><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach" target="_blank">MDN: Array.prototype.forEach()</a></p>
								        </div>
								    </div>
								    <div class="accordion_item">
								        <h3>
								            <button type="button" class="accordion_trigger button" aria-expanded="false">
								                <span>Element: classList property</span>
								                <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" class="ionicon" viewBox="0 0 512 512"><path fill="none" stroke="" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" d="M256 112v288M400 256H112"/></svg>
								            </button>
								        </h3>
								        <div class="accordion_panel" role="region">
								            <p>The read-only classList property of the Element interface contains a live DOMTokenList collection representing the class attribute of the element. This can then be used to manipulate the class list.</p>
								            <p><a href="https://developer.mozilla.org/en-US/docs/Web/API/Element/classList" target="_blank">MDN: Element: classList property</a></p>
								        </div>
								    </div>
								    <div class="accordion_item">
								        <h3>
								            <button type="button" class="accordion_trigger button" aria-expanded="false">
								                <span>Element: getAttribute() method</span>
								                <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" class="ionicon" viewBox="0 0 512 512"><path fill="none" stroke="" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" d="M256 112v288M400 256H112"/></svg>
								            </button>
								        </h3>
								        <div class="accordion_panel" role="region">
								            <p>The getAttribute() method of the Element interface returns the value of a specified attribute on the element.</p>
								            <p>If the given attribute does not exist, the value returned will be null.</p>
								            <p><a href="https://developer.mozilla.org/en-US/docs/Web/API/Element/getAttribute" target="_blank">Element: getAttribute() method</a></p>
								        </div>
								    </div>
								    <div class="accordion_item">
								        <h3>
								            <button type="button" class="accordion_trigger button" aria-expanded="false">
								                <span>Element: setAttribute() method</span>
								                <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" class="ionicon" viewBox="0 0 512 512"><path fill="none" stroke="" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" d="M256 112v288M400 256H112"/></svg>
								            </button>
								        </h3>
								        <div class="accordion_panel" role="region">
								            <p>The setAttribute() method of the Element interface sets the value of an attribute on the specified element.</p>
								            <p><a href="https://developer.mozilla.org/en-US/docs/Web/API/Element/setAttribute" target="_blank">Element: setAttribute() method</a></p>
								        </div>
								    </div>
								    <div class="accordion_item">
								        <h3>
								            <button type="button" class="accordion_trigger button" aria-expanded="false">
								                <span>HTMLElement: hidden property</span>
								                <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" class="ionicon" viewBox="0 0 512 512"><path fill="none" stroke="" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" d="M256 112v288M400 256H112"/></svg>
								            </button>
								        </h3>
								        <div class="accordion_panel" role="region">
								            <p>The HTMLElement property hidden reflects the value of the element's hidden attribute.</p>
								            <p><a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/hidden" target="_blank">HTMLElement: hidden property</a></p>
								        </div>
								    </div>
								</div>
							
						

The JavaScript

							
								function initAccordion() {
								    const root = document.querySelector(".accordion");
								    if (!root) return;
								    const items = root.querySelectorAll(".accordion_item");
								    const triggers = root.querySelectorAll(".accordion_trigger");

								    // first accordion is active and aria-expanded=true
								    items[0].classList.toggle("active");
								    triggers[0].setAttribute("aria-expanded", "true");

								    items.forEach((item) => {
								        const trigger = item.querySelector(".accordion_trigger");
								        trigger.addEventListener("click", () => {
								            // check for an active class
								            const isActive = item.classList.contains("active");
								            // on click, remove any active class
								            items.forEach((itm) => {
								                itm.classList.remove("active");
								                itm.querySelector(".accordion_trigger").setAttribute("aria-expanded", "false");
								            });
								            // add the active class if not active
								            if (!isActive) {
								                item.classList.add("active");
								                trigger.setAttribute("aria-expanded", "true");
								            }
								        });
								    });
								}
								initAccordion();