Sprung zum Inhalt

Webdesign nach Maß von webdesign weisshart

Bereiche anzeigen und verbergen mit Java­Script

Manchmal möchte man Bereiche auf einer Webseite erst bei Bedarf anzeigen, die Seite soll erst einmal übersichtlich und aufgeräumt sein. Erst nach einem Klick sollen Details gezeigt werden.

Denkbare Anwendungen:

Beispiel: Inhaltsverzeichnis

Hinweis: Die Links in diesem Beispiel funktionieren nicht – nur der aller!letzte.

Bild

Yin und Yang

Bildbeschreibung

Tai Chi, das Symbol für Yin und Yang

Yin und Yang sind zwei Begriffe aus der chinesischen Philosophie. Bei Yang handelt es sich um das Prinzip Sonne, bei Yin um das Prinzip Schatten. Der Übergang von Yin zu Yang ist dabei fließend.

Tai Chi, das Symbol für Yin und Yang, hat Kreisform.
Um Tai Chi zu erzeugen, gehen wir wie folgt vor:
Zuerst wird der Kreis durch eine gedachte senkrechte Mittellinie halbiert.
Diese Mittellinie wird in vier gleiche Teile unterteilt. Es entstehen also 3 Hilfspunkte auf der gedachten Mittellinie.
Um den obersten dieser 3 Hilfspunkte wird ein Halbkreis nach rechts geschlagen. Dieser beginnt am oberen Scheitelpunkt und endet im Mittelpunkt der Grafik.
Nun folgt ein identischer, aber spiegelbildlicher Halbkreis um den unteren der 3 Punkte. Dieser beginnt also im Zentrum der Grafik, wird nach links geschlagen, und endet im Fußpunkt der Grafik.
Die beiden Halbkreise bilden nun ein umgekehrtes "S", welches die Grafik in zwei identische, aber gegeneinander gedrehte Teile teilt (um 180°, also eine halbe Umdrehung gedreht). Die beiden Teile sind nicht nur identisch, sondern füllen auch die gesamte Grafik lückenlos aus.
Diese beiden Teile werden nun unterschiedlich eingefärbt. Der linke Teil weiß, der rechte schwarz.
Das Bild erinnert entfernt an 2 Kaulquappen – dicker Kopf und gekrümmter Schwanz – die sich innig umschlingen.
Jetzt noch ein Detail (das Bild mit den Kaulquappen wird damit noch deutlicher):
Um das Zentrum jedes der beiden "Köpfe", also um den obersten und untersten der 3 Hilfspunkte, wird ein kleiner Kreis geschlagen (mit einem Durchmesser entsprechend circa einem Viertel des "Kopfdurchmessers"). Dieser Kreis wird mit der Komplementärfarbe gefüllt, also Weiß im schwarzen Teil, und Schwarz im weißen Teil. Man könnte meinen, es handele sich um Augen.

Das Script

Eine Lösung auf Basis JavaScript wird hier beschrieben.
Diese Lösung ist weitgehend barrierefrei:

Hier wird das obige Beispiel eines Verzeichnisses mit mehreren Ebenen beschrieben. Alles, was zur Erzeugung der "Klapperei" erforderlich ist, wird in ein externes Script ausgelagert. Das Markup erhält lediglich eine zusätzliche Klasse "klappen".

Das Markup

... <li><a href="#unobtrusive">"Gutes" JavaScript?</a> <ul class="klappen"> <li><a href="#schichten">Das Drei-Schichten-Modell</a></li> <li><a href="#degrade">Graceful Degradation</a></li> <li><a href="#enhance">Progressive Enhancement</a></li> </ul> </li> ...

Der JavaScript Code

_________________________________________________________________________________________ Die "Klappfunktion" ein Script, um per Klick Bereiche aus- und einzublenden (CSS display:none) der aus-/einzublendende Bereich muss lediglich die Klasse "klappen" erhalten im Elternelement dieses Bereichs wird das angezeigt, was mit den Variablen »zeigen« und »aus« definiert ist. Script by webdesign weisshart Dipl.-Ing.(FH) Fritz Weisshart & Co. GbR http://webdesign.weisshart.de/ Das Script darf frei verwendet werden. webdesign weisshart übernimmt keinerlei Gewähr für Fehlerfreiheit oder mögliche Schäden, die aus der Nutzung des Scripts entstehen. _________________________________________________________________________________________ var i, j, browser, elem; var zeigen = '<span aria-relevant="all">[+]<dfn> erweitern<\/dfn><\/span>'; var aus = '<span aria-relevant="all">[-]<dfn> reduzieren<\/dfn><\/span>'; /* http://www.dustindiaz.com/getelementsbyclass/ */ function getElementsByClass(searchClass,node,tag) { var classElements = []; if ( node === null ) {node = document;} if ( tag === null ) {tag = '*';} var els = node.getElementsByTagName(tag); var elsLen = els.length; var pattern = new RegExp("(^|\\s)"+searchClass+"(\\s|$)"); for (i = 0, j = 0; i < elsLen; i++) { if ( pattern.test(els[i].className) ) { classElements[j] = els[i]; j++; } } return classElements; } function klapp(nr) { if (document.getElementById('kl'+nr)) { if ((this['show'+nr]) !== false) { document.getElementById('klapp'+nr).innerHTML = zeigen; (this['show'+nr]) = false; document.getElementById('kl'+nr).style.display = 'none'; } else if ((this['show'+nr]) === false) { document.getElementById('klapp'+nr).innerHTML = aus; (this['show'+nr]) = true; document.getElementById('kl'+nr).style.display = 'block'; } } } // Separation of functionality - onclicks schreiben function on_click(mr){ var links = document.getElementById('klapp'+mr); links.onclick = function() { klapp(mr); return false; }; } function init_klapp(){ if(navigator.userAgent.indexOf("MSIE") !== -1) { browser = "ms"; } else { browser = "gut"; } var e2 = getElementsByClass('klappen',document,'*'); for (var m = 0; m < e2.length; m++) { // jedem Node eine id zuweisen, damit er angesprochen werden kann: var att = document.createAttribute("id"); att.nodeValue = "kl"+m; e2[m].setAttributeNode(att); if (e2[m].nodeName == "UL" || e2[m].nodeName == "OL" && e2[m].parentNode.nodeName == "LI") { // der typische Anwendungsfall: verschachtelte Liste: elem = e2[m].parentNode; } else if (browser == "ms") { // zwei aufeinanderfolgende Blockelemente: elem = e2[m].previousSibling; } else if (browser == "gut") { elem = e2[m].previousSibling.previousSibling; } // ein a hinzufügen, (das später mit +/- belegt wird): var neuS = document.createElement("a"); var neuSpanText = document.createTextNode(""); neuS.appendChild(neuSpanText); elem.insertBefore(neuS, elem.firstChild.nextSibling); // dem eben erzeugten a eine id zuweisen: var att2 = document.createAttribute("id"); att2.nodeValue = "klapp"+m; elem.firstChild.nextSibling.setAttributeNode(att2); // und jetzt noch ein href Attribut: var att4 = document.createAttribute("href"); // att4.nodeValue = "#"; ist void(0) besser? att4.nodeValue = "javascript:void(0);"; elem.firstChild.nextSibling.setAttributeNode(att4); // dem Parent bzw. previous aria live Attribut hinzufügen elem.setAttribute('aria-live', 'polite'); // erst mal alles zuklappen: if (document.getElementById('klapp'+m)) { klapp(m); on_click(m);} } }

Download des aktuellen Scripts (rechte Maustaste - Ziel speichern unter)

Hinweis: Im Download fehlt eventuell die Funktion getElementsByClass, oder sie ist auskommentiert. Diese nützliche Funktion gibt es bei dustindiaz. Oder halt obigen Sourcecode kopieren.

Einbinden des Scripts im <head> Bereich:

<script type="text/javascript" src="/scripts/klapp_sub.js"></script>

Nun das Script aufrufen. Beim Aufruf werden alle Bereiche erst einmal "zugeklappt".

<script type="text/javascript">addEvent(window, 'load', init_klapp);</script>

Hinweis: Diese – korrekte – Art, ein Script aufzufrufen, wird bei ichwill.net/chapter4.html beschrieben. Dort, sowie bei www.scottandrew.com/weblog/ articles/cbs-events gibt es auch die für diese Methode erforderliche Funktion addEvent.

Nach dem Laden der Seite und Ausführung des Scripts "sieht" der Browser dies:

Der Generated Content

... <li aria-live="polite"> <a href="#unobtrusive">"Gutes" JavaScript</a> <a href="#" id="klapp0"> <span aria-relevant="all">[+]<dfn> erweitern</dfn></span></a> <ul style="display: none;" id="kl0" class="klappen"> <li><a href="#schichten">Das Drei-Schichten-Modell</a></li> <li><a href="#degrade">Graceful Degradation</a></li> <li><a href="#enhance">Progressive Enhancement</a></li> </ul> </li> ...

15 Kommentare

  1. philosapiens schrieb am Montag, 14.09.09 08:46 Uhr:

    Hallo Fritz,

    vielen Dank für Deine, wieder einmal, erhellenden Gedanken zum Thema Barrierefreiheit im Netz!
    Ich finde die Vorgehensweise interessant. Doch fällt mir leider wirklich kein plausibler Grund ein, die hover-Funktion durch JavaScript zu ersetzen. Wenn ich schon ein verschachteltes, mehrebeniges Menü brauche, dann realisiere ich das eben mit der CSS-Pseudoklasse :hover. Ich empfinde klappbare Menüs mit "Klickvoraussetzung" persönlich nicht so komfortabel. Auch Deine anderen Ideen, wie die Bildanzeige oder -beschreibung würde ich eher über hover darstellen.
    Aber ich gelobe hier zu schreiben, sollte mir dennoch nach längerem Nachforschen eine für mich interessante Verwendungsmöglichkeit in den Sinn kommen.

    Trotz Allem gefällt mir sehr, Deine bislang schon standardisierte wai-aria-Mitnutzung durch JavaScript!

    Vielen Dank!

    philosapiens

  2. Fritz schrieb am Montag, 14.09.09 11:42 Uhr:

    Hallo philosapiens,

    danke für den Hinweis.
    sei doch bitte so nett, und nenne mir ein CSS-only Beispiel, das auch mit dem IE funktioniert, und mit der Tastatur "komfortabel" bedienbar ist.
    Und Bildbeschreibung über :hover einblenden? Und wenn du eine längere Beschreibung scrollen musst, dann wird "enthovert"? Oder habe ich das falsch verstanden?
    Im Klartext: Ich kann mir sehr gut vorstellen, dass es Anwendungen gibt, wo ein Klick und nicht ein hover gewünscht ist. Nach einem Klick bleibt der gewählte Zustand erhalten. Hovern hingegen kann, vor allem für User mit schlechter Feinmotorik, eine kniffelige Angelegenheit sein.

  3. Fritz (Gast) schrieb am Samstag, 02.10.10 14:00 Uhr:

    @philosapiens

    Nach einem Jahr ein Argument nachgereicht für die hier vorgestellte JavaScript-Technik und gegen die Verwendung von CSS hover:

    Ich hab' mal zum Spaß auf dieser Seite (und nur auf dieser) für das iPhone (und nur für das iPhone) das Hauptmenü klappbar gemacht.

    Klappt! ;-)

  4. u.gottlieb schrieb am Samstag, 14.05.11 13:51 Uhr:

    hallo.

    sehr interessantes script, nur das es ueberhaupt nicht funktioniert.
    Habe das script klapp_sub.js heruntergeladen und im head eingebunden, das markup nur mit class="klappen" versehen und selbst bei java script aktiviert wird der ganze inhalt der ja versteckt sein soll angezeigt. Wo zum beispiel muss ich den aufruf "addEvent(window, 'load', init_klapp);"
    einfuegen, im head bereich oder body (beides probiert nichts funktioniert) (???)
    freue mich ueber kurze info.
    u.gottlieb

  5. Fritz schrieb am Samstag, 14.05.11 15:02 Uhr:

    @ u.gottlieb

    Was hast du hieran nicht verstanden:

    Hinweis: Diese - korrekte - Art, ein Script aufzufrufen, wird bei ichwill.net/chapter4.html beschrieben. Dort, sowie bei www.scottandrew.com/weblog/ articles/cbs-events gibt es auch die für diese Methode erforderliche Funktion addEvent.

  6. Christoph Jochum schrieb am Montag, 19.09.11 01:20 Uhr:

    Hallo Fritz,
    ich habe gerade festgestellt dass im IE 9 das Aufklappen des "Yin und Yang" Bildes und des dazu gehörenden Textes nicht funktioniert. Sowohl das Bild als auch der Text sind von Anfang an aufgeklappt und bleiben auch aufgeklappt, so als wäre javascript deaktiviert.

    Das aufklappbare Submenü hingegen läuft problemlos.

    Da ich diese Funktion gern verwenden würde, wäre ich dankbar für einen Tipp.

    Viele Grüße
    Christoph

  7. Fritz schrieb am Montag, 19.09.11 01:59 Uhr:

    Hallo Christoph,

    IE 9 - damit hast du mir erst einmal einen Schrecken eingejagt. Das Teil ist nämlich so buggy, dass ich es hier erst einmal verbannt habe, und den IE 8 wieder installiert - zum Testen, nicht zum Arbeiten.
    Aber jetzt zu deinem Punkt: unter Windows 7 / IE 9 konnte ich den von dir beschriebenen Fehler leider nicht nachvollziehen?

  8. Christoph Jochum schrieb am Montag, 19.09.11 03:10 Uhr:

    Hallo Fritz,
    danke für die schnelle Anwort zu später Stunde ... ich bin mal wieder bei meinen Schwiegereltern in Virgina, und hier ist es gerade mal 21:00.
    Ich habe noch Vista auf meinem Laptop, und da tritt der Fehler beim IE9 auf.
    Mit dem IETester kommt der Fehler bei IE5, IE9 und IE10, während mit IE6, IE7 und IE8 alles gut klappt.
    Wenn Dir irgendwas einfällt, lass es mich bitte wissen.
    So viel zum Internet Exploder.
    viele Grüße
    Christoph

  9. Christoph Jochum schrieb am Samstag, 24.09.11 16:13 Uhr:

    Hallo Fritz,
    ich habe mal die folgende Zeile:

    if(navigator.userAgent.indexOf("MSIE" ) !== -1) {

    geändert in:

    if((navigator.userAgent.indexOf("MSIE 6")!== -1) ||
    (navigator.userAgent.indexOf("MSIE 7")!== -1) ||
    (navigator.userAgent.indexOf("MSIE 8")!== -1)) {

    Das funktioniert in allen IE >6 unter Vista. Warum es beim IE 6 nicht geht, ist mir unklar, aber das ist ja auch eigentlich egal. Man muss heute ja auch nicht unbedingt Web Texte in Sütterlin schreiben ;-).

    viele Grüße von Christoph

  10. Fritz schrieb am Samstag, 24.09.11 16:45 Uhr:

    Hallo Christoph,

    vielen Dank dafür. Ich hab's sofort mal in die Seite hier eingebaut.
    Zum IE6: Der sollte unter Vista eigentlich gar nicht mehr existieren:
    milkstyle.de/blog
    PS: Windows XP / IE 6 »klappt« ;-)

  11. Christoph Jochum schrieb am Sonntag, 25.09.11 03:08 Uhr:

    Hallo,
    ich habe mal versucht einen Link oder Button zu erzeugen, mit dem man alles gleichzeitig aufklappen oder zuklappen kann, hatte allerdings keinen Erfolg. Es wäre schön, wenn da mal jemand eine Idee hätte.
    Grüße Christoph

  12. Fritz schrieb am Sonntag, 25.09.11 23:26 Uhr:

    @Christoph
    dazu braucht es doch wirklich nur einen Bruchteil des hier vorgestellten Codes. Und deine (einfache) Aufgabenstellung ist geradezu ideal, um in JavaScript einzusteigen.

  13. chris.jochum@t-online.de schrieb am Donnerstag, 29.09.11 04:03 Uhr:

    Hallo Fritz,
    ... habe ich ja versucht, mit diesem Link:

    <a href="javascript:klapp(0),klapp(1),klapp (2);">alles schließen oder öffnen</a>

    Das klappt auch, aber nur wenn alle zu oder alle offen sind. Ist nur ein Teil der Bereiche offen, wird der jeweilige Zustand umgekehrt.

    Gruß Christoph

  14. Fritz schrieb am Donnerstag, 29.09.11 11:52 Uhr:

    Hallo Christoph,

    bitte schau dir die Funktion
    function klapp(nr) {
    an. Dort insbesondere die if-Abfrage:
    if ((this['show'+nr]) !== false) { ...
    Dann wird dir sicher klar, warum die Funktion toggelt.

    Aber ich glaube jetzt, deine Absicht zu verstehen: Du willst die Funktionalität "alle zuklappen" [bzusätzlich[/b] zur Funktionalität dieses Scripts, nicht anstelle von.

    Du wirst dir zwei neue Funktionen schreiben müssen, die du ohne weiteres aus der Funktion klapp(nr) ableiten kannst. Dort einfach die if-Abfrage weglassen.

  15. Christoph Jochum schrieb am Freitag, 30.09.11 17:35 Uhr:

    Hallo Fritz,
    ich hatte wohl Knöpfe auf den Augen und nicht gesehen, warum die Funktion toggelt und infolge dessen für meinen beabsichtigten Zweck in dieser From nicht verwendbar war.
    Ich habe die beiden Funktionen geschrieben, und nun klappt alles prima.
    vielen Dank und Grüße
    Christoph

Ihr Kommentar zu diesem Artikel:

Über Ihren Kommentar oder Ihre Frage zu diesem Artikel freue ich mich. Ich behalte mir jedoch vor, Einträge wider die guten Sitten, unsinnige Einträge, oder Spam kommentarlos zu entfernen.