da ich in der letzten Zeit öfters mal eine Homepage für mich erstellt habe und auf der ein oder anderen Seite ein Inhaltsverzeichnis erstellt habe, habe ich mich mal damit beschäftigt, wie ich ein Inhaltsverzeichnis automatisch mithilfe von Javaskript erzeugen kann. Ich gehe mal davon aus, dass der ein oder andere das Gleiche vor hat.
Da das Inhaltsverzeichnis noch stylebar sein soll, muss es flexibel gehalten werden. Zudem sollte es einfach zu benutzen sein.
Das Inhaltsverzeichnis soll aus den Titeln (h1, h2, h3,...) erzeugt werden.
Für dieses Inhaltsverzeichnis müssen wir ersteinmal drei Variablen erstellen.
Code javascript:
1 2 3 | var headerText = '<ul id="ul1">'; // Hier wird der Text abgespeichert, der später in das HTML geschrieben wird
var lastDepth = 1; // Gibt die letzte Überschriftenebene an
var indexCounter = 0; // Dient einfach zum sicherstellen von eindeutigen Verweißen |
Die Titel können wir über document.getElementsByTagName(...) abfragen. Allerdings können wir nicht einfach document.getElementsByTagName("h1") aufrufen, da so die Reihnfolge der Titel (nicht h1) verloren gehen würde. Deshalb übergeben wir ein * um damit alle Elemente aus der HTML-Datei zu erhalten.
Damit wir nun nur die Title erhalten, bauen wir in der for-Schleife - um über alle Elemente zu iterieren - eine if-Bedingung ein, in der wir überprüfen, ob das Element ein Titel ist.
Code javascript:
1 2 3 4 5 6 7 | var headers = document.getElementsByTagName('*');
for (var i = 0; i < headers.length; i++ ) {
var header = headers[i];
if (header.tagName.match(/^h[1-6]$/i)) {
}
} |
Damit der Benutzer die Wahl hat, wieviele Ebenen das Inhaltsverzeichnis besitzen soll, übergeben wir an diese Funktion einen Parameter 'maxDepth'. Um nun die Überschriften zu filtern, die der Benutzer haben will, müssen wir noch die Ebene aus dem Titel-Tag filtern. Mit einer if-Bedingung werden dann nur die Titel durchgelassen, die in der richtigen Ebene sitzen.
Beispiel:
Code javascript:
1 | createIndex(2); // Zeigt nur die Titel h1 und h2 im Inhaltsverzeichnis an |
Code javascript:
1 2 3 4 5 6 7 8 9 | function createIndex(maxDepth) {
...
if (header.tagName.match(/^h[1-6]$/i)) {
var headerDepth = header.tagName.substring(1,2);
if(maxDepth >= headerDepth) {
addHeader(header, headerDepth); // Titel mit Ebene in neuer Funktion zur Variable 'headerText' hinzufügen
}
}
} |
In der Funktion 'addHeader(header, depth)' fügen wir den Titel an seinen richtigen Platz (Das war auch das kniffligste an der Sache).
Zu ersteinmal müssen wir für die Differenz der aktuellen und der letzten Ebene berechnen, um die Struktur zu erhalten.
Code javascript:
1 | var depthDiff = lastDepth - depth; |
Code javascript:
1 2 | var headerStr = header.firstChild.data;
header.id = headerStr+'.'+indexCounter; // ID generieren wir aus Titel-Text und dem indexCounter für die Eindeutigkeit (falls ein Titel doppelt vorkommt) |
Jetzt kommt der knifflige Teil. Wir müssen nun in den Listen-Ebenen von einer Ebene in die andere "hüpfen" können, sodass wir von Ebene 3 in Ebene 1 zurück kommen und umgekehrt.
Um von Ebene 1 in Ebene 3 zu kommen, erzeugen wir in einer for-Schleife so oft eine neue Liste, bis wir in der richtigen Ebene angelangt sind. Anschließend fügen wir dieser Liste den Titel mit internen Verweiß hinzu.
Code javascript:
1 2 3 4 5 6 7 | if(depth > lastDepth) {
depthDiff = depthDiff * -1;
for(var i = depthDiff; i > 1; i--) {
headerText = headerText + '<ul id="ul'+i+'">';
}
headerText = headerText + '<ul id="ul'+depth+'"><li id="h'+depth+'"><a href="#' + headerStr + '.' + indexCounter + '">' + headerStr + '</a>';
} |
In die andere Richtung (Ebene 3 auf Ebene 1) geht dann so:
Code javascript:
1 2 3 4 5 6 | else if(depth < lastDepth) {
for(var i = depthDiff; i > 1; i--) {
headerText = headerText + '</ul>';
}
headerText = headerText + '</ul><li id="h'+depth+'"><a href="#' + headerStr + '.' + indexCounter + '">' + headerStr + '</a>';
} |
Ist ein Titel in der gleichen Ebene, wie sein Vorgänger, so brauchen wir keinen Ebenenwechsel vornehmen und können den Titel direkt hinzufügen.
Code javascript:
1 2 3 | else {
headerText = headerText + '</li><li id="h'+depth+'"><a href="#' + headerStr + '.' + indexCounter + '">' + headerStr + '</a></li>';
} |
Am Ende von dieser Methode müssen wir nun nur noch den indexCounter um eins erhöhen und die lastDepth auf die aktuelle Depth setzen.
Code javascript:
1 2 | indexCounter++;
lastDepth = depth; |
Damit unser Inhaltsverzeichnis jetzt noch auf der Homepage angezeigt wird, müssen wir am Ende von der createIndex(maxDepth) den Text noch dort hinzufügen. Ich habe das mittels eines div-Elements gelöst, da dies der einfachste Weg ist und sich dieses noch schön gestalten lässt.
Code javascript:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | function createIndex(maxDepth) {
var headers = document.getElementsByTagName('*');
for (var i = 0; i < headers.length; i++ ) {
var header = headers[i];
if (header.tagName.match(/^h[1-6]$/i)) {
var headerDepth = header.tagName.substring(1,2);
if(maxDepth >= headerDepth) {
addHeader(header, headerDepth);
}
}
}
var indexDiv = document.getElementById('Index');
indexDiv.innerHTML = headerText+'</ul>';
} |
Das Inhaltsverzeichnis können wir nun ganz einfach durch folgenden Aufruf in unserer HTML-Datei erzeugen:
HTML-Code:
<body onLoad="createIndex(3)"> <div id="Index"></div> <h1>Überschrift1</h1> <h2>Überschrift2</h2> <h3>Überschrift3</h3> <h1>Überschrift1</h1> </body>
Auf die Überschriften kann man im CSS über #h1, #h2, #h3, etc., auf das div-Element über #Index und auf die Listen über #ul1, #ul2, #ul3, etc. zugreifen. Als Beispiel:
Code css:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | #Index {
border-bottom: 1px solid black;
}
#ul1 {
list-style-type: none;
}
#ul2 {
list-style-type: square;
}
#ul3 {
list-style-type: circle;
}
#h1 a {
color: #FF0000;
text-decoration: none;
}
#h2 a {
color: #00FF00;
text-decoration: none;
}
#h3 a {
color: #0000FF;
text-decoration: none;
} |
Eine Beispiel-HTML-Datei und Indexer.js habe ich für euch unten angehangen.
Ich hoffe euch hat mein Tutorial gefallen. Für Anregungen und Verbesserungsvorschläge bin ich selbstverständlich offen.

Gruß
Fabio


Bereiche
Kategorien
Forum - Webmaster & Internet
tutorials.de-Systemmitteilung