Dynamisches Inhaltsverzeichnis auf Webflow CMS – Der einfachste Weg

Veröffentlicht: 2022-03-22
Wir haben es kürzlich möglich gemacht, aktive Zustände zu einem klebrigen Inhaltsverzeichnis hinzuzufügen – Anweisungen finden Sie am Ende des Artikels!

Hintergrund

Bei Flowrite haben wir vor kurzem damit begonnen, längere Inhaltsstücke zu schreiben und wollten unsere Blogs besser lesbar machen, beginnend mit dem grundlegendsten Element – ​​dem Inhaltsverzeichnis.

Wir verwenden Webflow und lieben es absolut, aber es stellte sich heraus, dass das Erstellen von skalierbaren Inhaltsverzeichnissen für CMS-Elemente nicht so einfach war. Alle bestehenden Lösungen verlassen sich entweder darauf, IDs und Links manuell festzulegen oder Plugins von Drittanbietern zu verwenden.

Wir wollten ein einfaches System, das Inhaltsverzeichnisse basierend auf den Überschriften in unseren Blogs automatisch generiert. Das haben wir gebaut, und hier ist, wie Sie dasselbe tun können!

Wie es funktioniert?

  1. Entwerfen Sie Ihre ToC-Elemente. Gestalten Sie sie nach Ihren Wünschen – erstellen Sie Hover-Zustände, Animationen usw.
  2. Erstellen Sie irgendwo auf Ihrer CMS-Seite ein div für das Inhaltsverzeichnis mit einer bestimmten ID.
  3. Fügen Sie einen Code am Ende des <body>-Tags auf Ihrer CMS-Seite ein.
  4. ToCs werden automatisch für jedes CMS-Element generiert.

Erstellen Sie Ihr dynamisches Inhaltsverzeichnis

Entwerfen Sie Ihre ToC-Elemente

Geben Sie Ihrem ToC-Element eine Klasse (wir verwenden „tocitem“) und gestalten Sie es nach Ihren Wünschen.

Meine Empfehlung ist, eine separate, private Seite für die Gestaltung dieser Elemente zu verwenden. Auf diese Weise können Sie das Design später bei Bedarf leicht ändern.

Uns gefiel die Einfachheit der Elemente des Inhaltsverzeichnisses von Notion, also haben wir das als Benchmark verwendet.


Wenn Sie mehr als nur eine Art von Überschriften aufnehmen möchten, stellen Sie sicher, dass Sie ihnen eine zusätzliche Klasse zuweisen ("toc-h2", "toc-h3" usw.)

Erstellen Sie das Element für Ihr Inhaltsverzeichnis

Fügen Sie ein div hinzu, wo immer Sie Ihr Inhaltsverzeichnis haben möchten, und geben Sie ihm eine ID "toc". Auch hier können Sie dieses Element beliebig gestalten.

Wenn Sie Ihr Inhaltsverzeichnis in Ihrem Rich-Text-Element haben möchten, finden Sie weitere Einzelheiten am Ende dieses Artikels.

Zuletzt geben Sie dem Rich-Text-Element eine ID "Inhalt". Dies wird später benötigt, um sicherzustellen, dass wir die richtigen Überschriften im Inhaltsverzeichnis verwenden.

Wählen Sie aus zwei Optionen

Da die Inhaltsverzeichnisse automatisch generiert werden, müssen wir angeben, welche Überschriften wir darin aufnehmen möchten. In diesem Beitrag behandeln wir zwei Optionen:

  1. Generieren von Inhaltsverzeichnissen basierend auf nur einem einzigen statischen Überschriftentyp, z. B. H2s.
  2. Generieren von ToCs basierend auf mehreren Überschriften Ihrer Wahl – zum Beispiel H2s und H3s für einen Blogbeitrag und H2s und H4s für einen anderen.

Option 1: Inhaltsverzeichnisse mit einer Überschrift

Bei dieser Option werden Inhaltsverzeichnisse immer auf der Grundlage derselben Überschrift erstellt.

Fügen Sie den folgenden Code am Ende Ihres <body>-Tags auf Ihren Sammlungsseiten ein. Sehen Sie sich die Kommentare am Ende jeder Zeile an, wenn Sie verstehen möchten, wie es funktioniert.

  <script> document.getElementById("content").querySelectorAll("h2").forEach(function(heading, i) { // runs a function for all h2 elements inside your rich text element heading.setAttribute("id", "toc-" + i); // gives each h2 a unique id let str = heading.innerHTML; // adds section titles to slugs str = str.replace(/\s+/g, '-').replace(/[°&\/\\#,+()$~%.'":;*?<>{}]/g, "").toLowerCase(); // replaces spaces with hyphens, removes special characters and extra spaces from the headings, and applies lowercase in slugs heading.setAttribute("id", str); // gives each heading a unique id const item = document.createElement("a"); // creates an anchor element called "item" for each h2 item.innerHTML = heading.innerHTML // gives each item the text of the corresponding heading item.setAttribute("class", "tocitem"); // gives each item the correct class item.setAttribute("href", "#" + str); // gives each item the correct anchor link document.querySelector("#toc").appendChild(item); // places each item inside the Table of Contents div }); </script>
<script> document.getElementById("content").querySelectorAll("h2").forEach(function(heading, i) { // runs a function for all h2 elements inside your rich text element heading.setAttribute("id", "toc-" + i); // gives each h2 a unique id let str = heading.innerHTML; // adds section titles to slugs str = str.replace(/\s+/g, '-').replace(/[°&\/\\#,+()$~%.'":;*?<>{}]/g, "").toLowerCase(); // replaces spaces with hyphens, removes special characters and extra spaces from the headings, and applies lowercase in slugs heading.setAttribute("id", str); // gives each heading a unique id const item = document.createElement("a"); // creates an anchor element called "item" for each h2 item.innerHTML = heading.innerHTML // gives each item the text of the corresponding heading item.setAttribute("class", "tocitem"); // gives each item the correct class item.setAttribute("href", "#" + str); // gives each item the correct anchor link document.querySelector("#toc").appendChild(item); // places each item inside the Table of Contents div }); </script>

Veröffentlichen Sie die Website und Sie können loslegen

Option 2: Inhaltsverzeichnisse mit mehreren Überschriften

Diese Option gibt Ihnen die Möglichkeit, von Fall zu Fall zu bestimmen, welche Überschriften zum Generieren der Inhaltsverzeichnisse verwendet werden.

Beginnen wir damit, ein neues Textfeld in Ihrer Sammlung zu erstellen. Wir nennen es "Inhaltsverzeichnis basierend auf...". Hier geben Sie die Überschriften an, die im Inhaltsverzeichnis jedes CMS-Elements verwendet werden. Trennen Sie mit einem Komma und verwenden Sie keine Leerzeichen.


Fügen Sie nun den folgenden Code am Ende Ihres <body>-Tags auf Ihren Sammlungsseiten ein. Sehen Sie sich die Kommentare am Ende jeder Zeile an, wenn Sie verstehen möchten, wie es funktioniert.

  <script> document.getElementById("content").querySelectorAll("[HEADINGS]").forEach(function(heading, i) { // runs a function for all headings inside your rich text element let str = heading.innerHTML; // adds section titles to slugs str = str.replace(/\s+/g, '-').replace(/[°&\/\\#,+()$~%.'":;*?<>{}]/g, "").toLowerCase(); // replaces spaces with hyphens, removes special characters and extra spaces from the headings, and applies lowercase in slugs heading.setAttribute("id", str); // gives each heading a unique id const item = document.createElement("a"); // creates an anchor element called "item" for each heading item.innerHTML = heading.innerHTML; // gives each item the text of the corresponding heading ("[HEADINGS]").split(",").forEach(function(x) { // runs a function for each item in your headings list if (heading.tagName.toLowerCase()==x) { item.classList.add("tocitem", "toc-" + x); // gives each item the correct class } }); item.setAttribute("href", "#" + str); // gives each item the correct anchor link document.querySelector("#toc").appendChild(item); // places each item inside the Table of Contents div }); </script>
<script> document.getElementById("content").querySelectorAll("[HEADINGS]").forEach(function(heading, i) { // runs a function for all headings inside your rich text element let str = heading.innerHTML; // adds section titles to slugs str = str.replace(/\s+/g, '-').replace(/[°&\/\\#,+()$~%.'":;*?<>{}]/g, "").toLowerCase(); // replaces spaces with hyphens, removes special characters and extra spaces from the headings, and applies lowercase in slugs heading.setAttribute("id", str); // gives each heading a unique id const item = document.createElement("a"); // creates an anchor element called "item" for each heading item.innerHTML = heading.innerHTML; // gives each item the text of the corresponding heading ("[HEADINGS]").split(",").forEach(function(x) { // runs a function for each item in your headings list if (heading.tagName.toLowerCase()==x) { item.classList.add("tocitem", "toc-" + x); // gives each item the correct class } }); item.setAttribute("href", "#" + str); // gives each item the correct anchor link document.querySelector("#toc").appendChild(item); // places each item inside the Table of Contents div }); </script>

Stellen Sie schließlich sicher, dass Sie [HEADINGS] durch den Wert Ihres CMS-Felds „ToC based on…“ ersetzen.


Das war's, Sie sind bereit für die Veröffentlichung.

Anpassung

Aktive Zustände in einem klebrigen Inhaltsverzeichnis

Inspiriert von Chris Coyiers Beitrag zu CSS-Tricks haben wir eine Möglichkeit entwickelt, aktiven Inhalten zu sichtbaren ToC-Elementen hinzuzufügen – eine großartige Funktion für Sticky ToCs.

Fügen Sie zunächst "observer.observe(heading);" hinzu. am Anfang des Codes, den Sie zuvor implementiert haben. Sehen Sie sich den Screenshot für den richtigen Speicherort an.

Fügen Sie dann das folgende Code-Snippet über dem gesamten vorhandenen ToC-Code hinzu:

  <script> const observer = new IntersectionObserver(entries => { entries.forEach(entry => { const id = entry.target.getAttribute("id"); if (entry.isIntersecting) { document.querySelectorAll(".active").forEach((z) => { z.classList.remove("active") }); document.querySelector(`a[href="#${id}"]`).classList.add("active"); } }); }, { rootMargin: '0px 0px -75% 0px' }); </script>
<script> const observer = new IntersectionObserver(entries => { entries.forEach(entry => { const id = entry.target.getAttribute("id"); if (entry.isIntersecting) { document.querySelectorAll(".active").forEach((z) => { z.classList.remove("active") }); document.querySelector(`a[href="#${id}"]`).classList.add("active"); } }); }, { rootMargin: '0px 0px -75% 0px' }); </script>

Der Code fügt einem sichtbaren Tocitem eine Klasse namens "active" hinzu und entfernt die Klasse, wenn ein neues Tocitem erscheint.

Stellen Sie zuletzt sicher, dass Sie die "aktive" Klasse gestalten, indem Sie ihr beispielsweise eine andere Hintergrundfarbe geben.

Inhaltsverzeichnisse nur für einige der CMS-Elemente anzeigen

Wenn auf einigen Ihrer CMS-Elemente keine ToC angezeigt werden sollen, führen Sie die folgenden Schritte aus:

‍ 1. Lassen Sie das Feld „Inhaltsverzeichnis basierend auf..“ leer.
Wenn Sie Option 1 verwenden, fügen Sie einen Schalter in Ihrer CMS-Sammlung hinzu, um anzugeben, ob die ToC angezeigt werden sollen oder nicht.

2. Machen Sie die Sichtbarkeit Ihres Inhaltsverzeichnis-Div abhängig von der Auswahl in Schritt 1.

3. Erstellen Sie am Anfang Ihres ToC-Code-Snippets eine if-Anweisung , um zu vermeiden, dass die Funktion ausgeführt wird, wenn das Feld leer ist. Denken Sie daran, mit "}" zu schließen.

Inhaltsverzeichnis in Ihrem Rich-Text-Element

Wenn Sie Ihr Inhaltsverzeichnis in Ihrem Rich-Text-Element platzieren möchten, können Sie das Inhaltsverzeichnis-Div-Element mit einem Einbettungscode replizieren.

Erstellen Sie ein benutzerdefiniertes Codeelement in Ihrem Rich Text und kopieren Sie „<div id="toc" class="toc"></div>“ in das Codefeld und fügen Sie es ein.


Wenn Sie nur für einige der CMS-Elemente ein Inline-Inhaltsverzeichnis und für andere ein "normales" Inhaltsverzeichnis haben möchten, müssen Sie ein paar zusätzliche Tricks anwenden:

1. Erstellen Sie einen Optionsselektor mit nur einer Option: ".getElementById('content'). Wählen Sie ihn bei den CMS-Elementen aus, bei denen Sie ein Inhaltsverzeichnis im Rich Text haben möchten.

2. Zeigen Sie das "normale" ToC nur an, wenn der Selektor nicht gesetzt ist.


3. Fügen Sie den Wert des Selektors dem folgenden Teil des Codes hinzu. Wenn nun der Selektor ausgewählt wurde, fügt der Code die ToC-Elemente innerhalb des richtigen ToC-Div an.

Vermeiden Sie die Überlagerung der Navigationsleiste beim Scrollen

Möglicherweise stellen Sie fest, dass die Seite beim Klicken auf einen Inhaltsverzeichnis-Link nach unten zur richtigen Überschrift scrollt, aber von Ihrer Navigationsleiste blockiert wird.

Um dies zu beheben:

  1. Stellen Sie sicher, dass die Position Ihres Navigationselements auf "fest" eingestellt ist
  2. Ändern Sie das Tag des Navigationselements in "Kopfzeile".

Das ist es! Falls Sie unterwegs auf Probleme gestoßen sind, zögern Sie nicht, mir eine E-Mail zu senden oder mich über Twitter / LinkedIn zu kontaktieren.

Ich würde auch gerne wissen, ob Sie dieses System letztendlich verwenden, also pingen Sie mich bitte an, wenn Sie dies getan haben, und teilen Sie den Beitrag mit jemand anderem, der davon profitieren könnte ️