Automatisches Mini-TOC mit Scroll Spy in Onlinedokumentation

In moderner Onlinedokumentation sind die Topics häufig recht lang und bestehen aus mehreren Abschnitten. Ein kleines, neben dem Text erscheinendes Inhaltsverzeichnis der Seite (Mini-TOC) schafft hier eine gute Orientierung. Mit einer geeigneten JavaScript-Bibliothek lässt sich ein solches kleines Verzeichnis vollautomatisch in alle Topics integrieren.

Ein Skript sucht dabei automatisch nach den im Topic vorkommenden Überschriften, baut daraus das Verzeichnis und verlinkt es.

Beispiel

Auch die Seite, die Sie gerade lesen, besitzt ein solches kleines Inhaltsverzeichnis (siehe links oben im Browserfenster – nur sichtbar bei ausreichender Größe des Browserfensters). In diesem Verzeichnis erscheinen automatisch alle Überschriften zweiter Ebene (h2-Elemente in HTML). Das Script überwacht kontinuierlich die aktuelle Scrollposition im Text (sog. Scroll Spy). Ein Balken visualisiert beim Scrollen die aktuelle Position innerhalb des Topics und schafft auf diese Weise zusätzliche Orientierung.

In einer Onlinedokumentation ist die linke Seite oft bereits durch das übergreifende Inhaltsverzeichnis der Gesamtdokumentation belegt. In diesem Fall können Sie das automatisch generierte Mini-TOC auch auf der rechten Seite erstellen lassen.

Implementierung

Die hier vorgestellte Lösung nutzt die Open-Source-JavaScript-Bibliothek scrollnav.js.

Ein wesentlicher Vorteil dieser Bibliothek im Vergleich zu anderen Bibliotheken derselben Art ist, dass hier die h2-Elemente im Text keine IDs besitzen müssen (nicht alle Redaktionssysteme stellen in den Überschriften IDs bereit oder ermöglichen es, IDs manuell zu setzen). Fehlen die IDs, erzeugt die Bibliothek die IDs zur Laufzeit automatisch.

Schritt 1: Verlinken Sie im Head-Abschnitt Ihrer Seitenvorlage auf die JavaScript-Datei der Bibliothek (passen Sie den Pfad wie erforderlich an).


<script src="YOUR-PATH/scrollnav.min.umd.js"></script>

Schritt 2: Ergänzen Sie folgenden CSS-Code in der von Ihrer Onlinedokumentation verwendeten CSS-Datei oder im Head-Abschnitt Ihrer Seitenvorlage.

Dieser Code enthält sowohl die Styles für das Verzeichnis als auch Codes, um später Inhalt und Verzeichnis nebeneinanderstellen zu können. Die Styles sind dabei so definiert, dass in schmalen Browserfenstern unterhalb 750 Pixeln sowie beim Drucken das Verzeichnis nicht sichtbar ist.

Mit den Einstellungen des Beispiels erscheint das Verzeichnis rechts neben dem Inhalt des Topics.


.scroll-nav__list {
  margin: 0;
  padding-left: 20px;
  list-style-type: none;
  border-left: solid;
  border-width: 1px;
  border-color: #c3c3c3;  
}
.scroll-nav__item {
  display: flex;
  align-items: center;
  justify-content: left;
  height: auto;
  margin-top: 1em;
  margin-bottom: 1em;
}
.scroll-nav__item--active {
}
.scroll-nav__item--active a:link {}
.scroll-nav__item--active a:visited {}  
.scroll-nav__item--active a:hover {}    
.scroll-nav__item--active::before {
  border-left: 3px solid rgb(34,34,34);
  content: '';
  height: 3em;
  left: 0;
  position: absolute;
}
.scroll-nav__link {
}
.mymenu a:link {color: #000 !important; text-decoration: none !important;}
.mymenu a:visited {color: #000 !important; text-decoration: none !important;}
.mymenu a:hover {color: #006699 !important;; text-decoration: underline !important;}
.mymenu {
  width: 350px;
  margin-left: 100px;
  float: right;
  position: sticky; top: 110px;
}
.mycontainer {
  width: auto;
  overflow: hidden;
}
@media screen and (max-width: 750px) {
 .mymenu {display: none;}
}
@media print {
 .mymenu {display: none;}
}

Schritt 3: Platzieren Sie in Ihrer Seitenvorlage am Beginn eines Topics zwei HTML-Schnipsel als Platzhalter für das zu generierende Inhaltsverzeichnis. Zwischen diesen beiden HTML-Schnipseln können Sie optional einen kurzen Text einfügen, der dann oberhalb des generierten Verzeichnisses erscheint. Beispielsweise können Sie eine Überschrift mit dem Text „Auf dieser Seite:“ oder etwas Ähnliches platzieren.


<div class="mymenu">

</div>

Schritt 4: Umschließen Sie den Inhalt des Topics mit folgenden zwei HTML-Schnipseln:


<div class="mycontainer">

</div>

Schritt 5: Binden Sie am Ende des Body-Abschnitts Ihrer Seitenvorlage folgenden JavaScript-Code ein, der das Script ausführt. Zu den darin enthaltenen Parametern siehe die Dokumentation zum Skript.

Tipp: Abweichend von der Dokumentation zum Skript sollten Sie den Code erst dann ausführen, wenn die Seite vollständig geladen ist, einschließlich aller Bilder. Andernfalls stimmen unter Umständen die berechneten Positionen nicht immer exakt und es kann vorkommen, dass das das Skript nicht immer genau zu den richtigen Stellen scrollt. Packen Sie daher das Ganze noch in den Befehl „window.onload“.


<script>
 const content = document.querySelector('.mycontainer');
 const sidebarCurrent = document.querySelector('.mymenu');
 function onPageLoaded() {
  scrollnav.init(content, {
   sections: 'h2',
   subSections: '',
   insertTarget: sidebarCurrent,
   insertLocation: 'append',
   easingStyle: 'easeOutQuint'
  });   
 }
 if (window.addEventListener) {
    // for modern browsers
    window.addEventListener("load", onPageLoaded);
 } else if (window.attachEvent) {
    // for older versions of Internet Explorer
    window.attachEvent("onload", onPageLoaded);
 } 
</script>

Zusätzliche Überschrift (1)

Dies ist nur ein Dummy-Abschnitt, um zur Demonstration eine weitere Überschrift zu erzeugen.

##### ##### ##### ### ##### ########### ########## ##### ### ## ###### ########## ######### ##### #### ###### ##### ##### ## ## ######### ########## ### #### ######### ##### ####### ###### ######### ############ ##### ### ###### ######## ## #### ## ########### ####### ###### ##### ######## # ##### #### ######## ########### ###### ###### ######

##### ##### ##### ### ##### ########### ########## ##### ### ## ###### ########## ######### ##### #### ###### ##### ##### ## ## ######### ########## ### #### ######### ##### ####### ###### ######### ############ ##### ### ###### ######## ## #### ## ########### ####### ###### ##### ######## # ##### #### ######## ########### ###### ###### ###### ## ######## ## ####### ########## ### ## ###### # ###### ####### ############# #### ######## ######## ####### ### ### #### ####### ###### ##### ####### #######

##### ###### ###### ######## ## ###### ######## ### ####### ####### ### ######## ########## ########### ### #### ######## ## #### ### ###### ########### ###### ##### ## ##### ### #### #### ########### ######## ############ ### ###### ########## ##### ###### ####### ### #### ##### ##### ######### #### ### ##### ######## ########## ##### ##### ######## ####### ### ######### ##### ##### ####### ##### ####### ###### ######### #### ####### ### #### ###### ##### ####### ### ######## # ######### ##### ############ #### ####### #### ##### ### ######### #### ######### ### ####### ####### #### # #### ######## ############# ### ###### ###### ####### ## ####### ### ######## #### ##### ##### ## ####### ##### #### ######## ###### ######### ########## ######### ##### ## #### ######### #######.

Zusätzliche Überschrift (2)

Ein weiterer Dummy-Abschnitt nur zur Demonstration.

##### ###### ###### ######## ## ###### ######## ### ####### ####### ### ######## ########## ########### ### #### ######## ## #### ### ###### ########### ###### ##### ## ##### ### #### #### ########### ######## ############ ### ###### ########## ##### ###### ####### ### #### ##### ##### ######### #### ### ##### ######## ########## ##### ##### ######## ####### ### ######### ##### ##### ####### ##### ####### ###### ######### #### ####### ### #### ###### ##### ####### ### ######## # ######### ##### ############ #### ####### #### ##### ### ######### #### ######### ### ####### ####### #### # #### ######## ############# ### ###### ###### ####### ## ####### ### ######## #### ##### ##### ## ####### ##### #### ######## ###### ######### ########## ######### ##### ## #### ######### #######.

##### ##### ##### ### ##### ########### ########## ##### ### ## ###### ########## ######### ##### #### ###### ##### ##### ## ## ######### ########## ### #### ######### ##### ####### ###### ######### ############ ##### ### ###### ######## ## #### ## ########### ####### ###### ##### ######## # ##### #### ######## ########### ###### ###### ###### ## ######## ## ####### ########## ### ## ###### # ###### ####### ############# #### ######## ######## ####### ### ### #### ####### ###### ##### ####### #######