Axels Homepage


 ≡ Download ≡ 
Template-Webseite
iframe_template.zip (10 kB)
Demo-Seite

Hinweis zu den Links
Problem mit einem Link?
 
Sie sind hier: » PC + Co. » Javascript » aufklappendes Menü

Javascript - aufklappbares Menü

Einleitung

Wenn man eine einfache statische Webseite mit einer handvoll Seiten hat, ist insbesondere das Menü mit Hervorhebung der richtigen Seite eine besondere Knacknuss.
Auch wenn Sie den nachfolgenden Teil nicht verstehen sollten: Im Download finden Sie eine Demo-Webseite vor, die ein dynamisches Menü enthält: wenn eine "bekannte" (also im Menü irgendwo verlinkte) Seite enhtalten ist, dann wird im Menü automatisch die richtige Seite hervorgehoben.

Vorab vielleicht eine Demo-Seite


Ansatz

Hier bietet sich Javascript an, ein Menü je nach geladener Seite das richtige Element hervorheben zu lassen. Man loopt über die A-Tags im Menü und prüft, ob die aktuelle URL im gerade geprüften Element enthalten ist. Wenn ja, dann wird die CSS-Klasse auf "active" gesetzt; wenn nicht, dann auf "".

var sDivMenu="divMenu"; // Name des DIVs mit Menü
var oMenudiv= parent.document.getElementById(sDivMenu);
var sClassActive="active";
var sClassInactive="";

if (oMenudiv) {
	var oLinks = oMenudiv.getElementsByTagName("a");
	if (oLinks) for (var i = 0; i < oLinks.length; i++) {
		sClass=sClassInactive;
		if (window.location.href.indexOf(oLinks[i].href)==0) {

			// Menue-Punkt aktiv:

			// Klasse setzen. Link-Markierung entfernen
			oLinks[i].className=sClassActive;
			oLinks[i].blur();
			(...)
		} else {

			// Menue-Punkt inaktiv:
			oLinks[i].className=sClassInactive;

		}
	}
}
JS-Code zum Markieren des aktiven Menü-Links


verschachtelte Menüs

Soweit klappt das Ganze mit Menüs, die nicht in einer Baumstruktur verschachtelt werden, denn nur der jeweils aktuelle Menüpunkt erhält die Klasse "active".

Wenn man ein Menü mit mehreren Ebenen möchte, muss man
  • bei Klick auf einen Menüpunkt testen, ob es einen Unterpunkt gibt. Wenn ja, soll es angezeigt werden.
  • andersherum, wenn man einen Link irgendwohin in eine tieferliegenden Seite hat, dann muss man testen, welches die Eltern-Seiten sind und diese aufklappen und als aktiv markieren.
Bei diesem Vorhaben kommt man um Vorgaben nicht umhin. HTML-konform sollte das Menü sein und eine Fallback-Variante aufweisen, falls jemand kein Javascript aktiviert hat.

HTML-Code

Der einzig HTML-konforme Ansatz, der logisch die Verschachtelung wiedergibt, ist die Darstellungsweise mit Listen mit UL.
Innerhalb eines LI-Listen-Elements wird eine weitere UL-Liste geöffnet, um eine weitere Verschachtelungs-Ebene zu öffnen.

Wenn es so aussehen sollte:

+-- Startseite
|
+-- über uns
|
+-- Hobbys
|   |
|   +-- Autos
|   |   +-- Audi
|   |   +-- BMW
|   |   +-- VW
|   |
|   +-- Zeichnen
|
+-- Kontakt
Struktur des verschachtelten Menüs

... kann man es wie folgt umsetzen:

<ul>
	<li><a href="pages/start.html"    >Startseite</a></li>
	<li><a href="pages/ueber.html"    >über uns</a></li>
	<li><a href="pages/hobbys.html"   >Hobbys</a>
		<ul>
			<li><a href="pages/hobbys_autos.html"   >Autos</a>
				<ul>
					<li><a href="pages/hobbys_autos_audi.html"  >Audi</a></li>
					<li><a href="pages/hobbys_autos_bmw.html"   >BMW</a></li>
					<li><a href="pages/hobbys_autos_vw.html"    >VW</a></li>
				</ul>
			</li>

			<li><a href="pages/hobbys_zeichnen.html">Zeichnen</a></li>
		</ul>
	</li>
	<li><a href="pages/kontakt.html"  >Kontakt</a></li>
</ul>
HTML-Code eines verschachtelten Menüs


Wie gesagt: das ist die Wiedergabe der logischen Struktur als HTML.
Wie das Ganze optisch dargestellt werden soll, dafür ist CSS zuständig.

Javascript

Hier kommt das DOM-Objekt ins Spiel. Ausgehend von den Linkobjekten kann man mit Hilfe der Unterobjekte nextSibling und parentNode durch die Objekte in der HTML-Struktur noch "unten" und "oben" springen. Dann kann man die Eigenschaften von tiefer- und höherliegenden Elementen verändern.

Wenn man sich den HTML-Code ansieht:

Unterhalb des A-Tags eines Links (im JS-Code wird jeder einzelne Link mit oLinks[i] abgehandelt) kann sich ein UL für eine tiefere Verschachtelung befinden. Wenn ich auf dem Menü "Hobbys" stehe, dann sollen das Untermenü aufgeklappt werden.

Oberhalb des A-Tags befindet sich ein LI, jeweils darüber ein UL. Um ein übergeordnetes Menü anzuzeigen, damit der eigene Menü-Link# sichtbar werden kann, sucht man den parentNode bzw. parentNode.parentNode:
oCurrent=oLinks[i];
oParentUL=oCurrent.parentNode.parentNode;
oParentLI=oCurrent.parentNode;

Mit Hilfe der while-Schleife wird beliebig viele Ebenen nach "oben" gegangen, bis es kein übergeordnetes UL mehr gibt.

Jetzt komen wir dazu, den Javascript-Code, der oben im ersten Beispiel noch mit (...) ausgeklammert war, zu ergänzen.
Den vollständigen Code finden Sie in der Demo-Seite in der ./js/globalfunctions.js mit der Funktion function updateMenu().

	if (window.location.href.indexOf(oLinks[i].href)==0) {

		// Menue-Punkt aktiv:

		// Klasse setzen. Link-Markierung entfernen
		oLinks[i].className=sClassActive;
		oLinks[i].blur();

		// tieferliegende UL sichtbar machen
		oNextS=oLinks[i].nextSibling;
		if (oNextS) {
			oNextUl=oNextS.nextSibling;
			if (oNextUl) oNextUl.style.display="block";
		}

		// uebergeordnete markieren
		oCurrent=oLinks[i];
		while (oCurrent) {
			oParentUL=oCurrent.parentNode.parentNode;
			oParentLI=oCurrent.parentNode;
			if (oParentUL) {
				oParentUL.style.display="block";

				if (oParentLI.firstChild) oParentLI.firstChild.className=sClassActive;

				oCurrent=false;
				if (oParentUL.parentNode.tagName=="LI") oCurrent=oParentUL;
			}
		}
	} else {

		// Menue-Punkt inaktiv:
		oLinks[i].className=sClassInactive;

		// tieferliegende UL verstecken
		oNextS=oLinks[i].nextSibling;
		if (oNextS) {
			oNextUl=oNextS.nextSibling;
			if (oNextUl) oNextUl.style.display="none";
		}
	}

JS-Code zur Anzeige des Menüs


Seitenanfang


 
©2010 by Axel Hahn - powered by
Valid HTML 4.01!