Beispiel: ohne großes Framework
Das hier vorgestellte Accordion basiert auf einem UL Element mit der Class "accordion", in den LI Elementen muss sich ein Element mit "sheet-header" befinden, dieses wird zum anclickbaren Titel im Accordion.
Folgende Einstellungen sind möglich:
- keine Attribute : es ist immer nur ein Element aktiv, ist beim Start keine Element aktiv wird das Erste per JavaScript aktiviert, sind beim Start mehrere aktiv bleibt nur das erste Aktive aktiv
- data-allclosed="true" : erlaubt auch das schließen aller Seiten und startet sobald kein Element activ ist auch komplett geschlossen
- data-multiselect="true" : mehrere Elemente können aktiv sein, aber auch kein Element, zum Start als auch zwischendurch
-
Udo
Udo Schmal Udo Schmal
Softwareentwicklung
E-Mail: udo.schmal@t-online.de -
Sammy
Sammy
E-Mail: sammy@gocher.me
HTML:
<!DOCTYPE html >
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Accordion</title>
<link rel="stylesheet" type="text/css" href="accordion.css" />
</head>
<body>
<ul class="accordion">
<li class="active">
<h4 class="sheet-header">Udo</h4>
<div class="imageLeft"><img border="0" height="257" width="190" src="/media/udo.jpg" alt="Udo Schmal" title="Udo Schmal" /></div>
<h5 id="udo">Udo Schmal</h5>
<p><strong>Softwareentwicklung</strong></p>
<table summary="Kontakt" class="noBorder">
<tbody>
<tr>
<td>E-Mail:</td>
<td><a href="mailto:udo.schmal@t-online.de">udo.schmal@t-online.de</a></td>
</tr>
</tbody>
</table>
</li>
<li>
<h4 class="sheet-header">Sammy</h4>
<div class="imageLeft"><img border="0" width="190" height="190" src="/media/gocher~c190.JPG" alt="Sammy" title="Sammy" /></div>
<h5 id="sammy">Sammy</h5>
<table summary="Kontakt" class="noBorder">
<tbody>
<tr>
<td>E-Mail:</td>
<td><a href="mailto:sammy@gocher.me">sammy@gocher.me</a></td>
</tr>
</tbody>
</table>
</li>
</ul>
<p><a href="#udo">Udo</a> oder <a href="#sammy">Sammy</a></p>
<script src="accordion.js"></script>
</body>
</html>
JavaScript:
// coding: utf-8
/*! Created by: Udo Schmal | https://www.gocher.me/ */
(function () {
'use strict';
var localLinks = document.querySelectorAll("[href^='#']");
function Accordion(accordion) {
let multiselect = accordion.dataset.multiselect === 'true';
let allclosed = accordion.dataset.allclosed === 'true';
let current = null;
let sheets = accordion.children;
let hash = window.location.hash;
let anchor = null;
if (hash) {
let id = hash.substr(1);
anchor = document.getElementById(id);
}
function toggle(event) {
let sheet = this.parentNode;
if (multiselect) {
sheet.classList.toggle("active");
} else {
if (current !== sheet) {
if (current) {
current.classList.remove("active");
}
current = sheet;
sheet.classList.add("active");
} else if (allclosed) {
if (current) {
current.classList.remove("active");
}
current = null;
}
}
}
for (let i = 0; i < sheets.length; i++) {
if (anchor && sheets[i].contains(anchor)) {
if (!multiselect && current) {
current.classList.remove("active");
}
sheets[i].classList.add("active");
current = sheets[i];
} else if (!multiselect && sheets[i].classList.contains("active")) {
if (current) {
sheets[i].classList.remove("active");
} else {
current = sheets[i];
}
}
let header = sheets[i].querySelector('.sheet-header');
header.setAttribute('tabindex', '0');
header.setAttribute('role', 'button');
header.addEventListener('click', toggle);
let ids = sheets[i].querySelectorAll("[id]");
for (let iId = 0; iId < ids.length; iId++) {
for (let ilocalLinks = 0; ilocalLinks < localLinks.length; ilocalLinks++) {
if (localLinks[ilocalLinks].href.split('#')[1] == ids[iId].id) {
localLinks[ilocalLinks].addEventListener('click', function (event) {
header.click();
});
}
}
}
}
if (!multiselect && !allclosed && !current && (sheets.length > 0)) {
sheets[0].classList.add("active");
current = sheets[0];
}
}
var accordionList = document.querySelectorAll("ul.accordion");
if (accordionList.length > 0) {
for (var i=0; i<accordionList.length; i++) {
if (accordionList[i].children && accordionList[i].children.length > 0) {
new Accordion(accordionList[i]);
}
}
// accessibility: handle tabindex enter keydown event
document.addEventListener('keydown', function(event) {
if (event.key === "Enter") {
if (event.target.parentNode && event.target.parentNode.classList.contains('accordion')) {
event.target.click();
}
}
});
}
})();
StyleSheet:
ul.accordion {
font-family: Arial,sans-serif;
position: relative;
margin: 0;
padding: 0;
list-style: none;
list-style-type: none;
}
ul.accordion .sheet-header {
margin-top: 0;
}
ul.accordion > li {
margin: 0 0 1px 0;
padding: 7px 10px 1px 10px;
border: 1px solid #C8CED0;
background-color: #fff;
border-radius: 4px;
overflow: hidden;
transition: max-height 0.25s ease-out;
max-height: 24px;
}
ul.accordion > li:not(.active):hover, ul.accordion[data-multiselect="true"] > li:hover {
cursor: pointer;
}
ul.accordion > li.active {
height: auto;
max-height: 1200px;
padding-bottom: 7px;
box-sizing: border-box;
transition: max-height 0.25s ease-in;
overflow: hidden;
}
ul.accordion > li .sheet-header {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
color: #666;
font-weight: bold;
}
@media print {
ul.accordion > li {
max-height: none;
}
}