Dynamiczny spis treści w Webflow CMS – Najprostszy sposób

Opublikowany: 2022-03-22
Niedawno umożliwiliśmy dodawanie aktywnych stanów do przyklejonego spisu treści – instrukcje znajdziesz na końcu artykułu!

Tło

We Flowrite niedawno zaczęliśmy pisać dłuższe teksty i chcieliśmy, aby nasze blogi były bardziej czytelne, zaczynając od najbardziej podstawowego elementu – spisu treści.

Korzystamy z Webflow i absolutnie go kochamy, ale okazało się, że tworzenie ToC skalowalnie dla elementów CMS nie było takie proste. Wszystkie istniejące rozwiązania opierają się na ręcznym ustawianiu identyfikatorów i linków lub przy użyciu wtyczek innych firm.

Chcieliśmy mieć prosty system, który automatycznie generowałby ToC na podstawie nagłówków naszych blogów. To właśnie zbudowaliśmy, a oto jak możesz zrobić to samo!

Jak to działa?

  1. Zaprojektuj swoje elementy ToC. Ustaw je tak, jak chcesz – twórz stany najechania, animacje itp.
  2. Utwórz div dla ToC z określonym identyfikatorem w dowolnym miejscu na swojej stronie CMS.
  3. Wstaw fragment kodu na końcu tagu <body> na swojej stronie CMS.
  4. ToCs są generowane automatycznie dla każdego elementu CMS.

Tworzenie dynamicznego spisu treści

Zaprojektuj swoje elementy ToC

Nadaj swojemu przedmiotowi ToC klasę (używamy „tocitem”) i stylizuj go w dowolny sposób.

Do projektowania tych elementów zalecam korzystanie z osobnej, prywatnej strony. W ten sposób możesz później łatwo zmodyfikować projekt, jeśli zajdzie taka potrzeba.

Podobała nam się prostota elementów spisu treści Notion, więc wykorzystaliśmy to jako punkt odniesienia.


Jeśli chcesz zawrzeć więcej niż jeden typ nagłówków, upewnij się, że nadałeś im dodatkową klasę ("toc-h2", "toc-h3" itp.)

Stwórz element dla swojego ToC

Dodaj element div w dowolnym miejscu, w którym chcesz umieścić swój ToC i nadaj mu identyfikator „toc”. Ponownie możesz nadać temu elementowi dowolny styl.

️.
Jeśli chcesz, aby Twój ToC znajdował się w elemencie tekstu sformatowanego, zobacz koniec tego artykułu, aby uzyskać więcej informacji.

Na koniec nadaj elementowi Rich Text identyfikator „content”. Będzie to potrzebne później, aby upewnić się, że używamy prawidłowych nagłówków w ToC.

Wybierz jedną z dwóch opcji

Ponieważ ToC będą generowane automatycznie, musimy wskazać, które nagłówki chcemy w nich uwzględnić. W tym poście omówimy dwie opcje:

  1. Generowanie ToC na podstawie tylko jednego statycznego typu nagłówka, na przykład H2.
  2. Generowanie ToC na podstawie wielu wybranych przez Ciebie nagłówków – na przykład H2 i H3 dla jednego posta na blogu oraz H2 i H4 dla drugiego.

Opcja 1: Warunki korzystania z jednego nagłówka

W tej opcji ToCs będą zawsze generowane na podstawie tego samego nagłówka.

Wstaw następujący kod na końcu tagu <body> na stronach swojej kolekcji. Zobacz komentarze na końcu każdej linii, jeśli chcesz zrozumieć, jak to działa.

  <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>

Opublikuj stronę i gotowe

Opcja 2: Wielonagłówkowe ToCs

Ta opcja daje możliwość określenia w każdym przypadku, które nagłówki zostaną użyte do wygenerowania ToC.

Zacznijmy od utworzenia nowego pola tekstowego w Twojej Kolekcji. Nazywamy to "TOC opartym na...". Tutaj określasz nagłówki, które będą używane w ToC każdego elementu CMS. Oddziel je przecinkiem i nie dodawaj spacji.


Teraz wstaw następujący kod na końcu tagu <body> na stronach kolekcji. Zobacz komentarze na końcu każdej linii, jeśli chcesz zrozumieć, jak to działa.

  <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>

Na koniec pamiętaj, aby zastąpić [NAGŁÓWKI] wartością pola CMS „ToC based on...”.


To wszystko, jesteś gotowy do publikacji.

Dostosowywanie

Stany aktywne w lepkim spisie treści

Zainspirowani postem Chrisa Coyiera na temat CSS-Tricks, stworzyliśmy sposób na dodawanie aktywnych stanów do widocznych elementów ToC – świetna funkcja dla przyklejonych ToCs.

Najpierw dodaj "observer.observe(heading);" na początku kodu, który zaimplementowałeś wcześniej. Zobacz zrzut ekranu dla prawidłowej lokalizacji.

Następnie dodaj następujący fragment kodu na wierzchu całego istniejącego kodu ToC:

  <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>

Kod dodaje klasę o nazwie „aktywna” do widocznego tocitemu i usuwa klasę, gdy pojawi się nowy tocitem.

Na koniec, upewnij się, że stylujesz „aktywną” klasę, na przykład nadając jej inny kolor tła.

Kąt

Wyświetlaj ToC tylko na niektórych elementach CMS

Jeśli nie chcesz, aby ToC pojawiało się w niektórych elementach CMS, wykonaj następujące czynności:

‍ 1. Pozostaw pole „ToC based on…” puste.
Jeśli korzystasz z Opcji 1, dodaj przełącznik w swojej kolekcji CMS, aby wskazać, czy ToC powinno się pojawiać, czy nie. Kąt

2. Uczyń widoczność swojego div ToC warunkową na podstawie selektora w kroku 1.

3. Utwórz instrukcję if na początku fragmentu kodu ToC, aby uniknąć uruchamiania funkcji, jeśli pole jest puste. Pamiętaj, aby zamknąć "}".

ToC wewnątrz elementu Rich Text

Jeśli chcesz umieścić ToC w elemencie Rich Text, możesz zreplikować element div ToC za pomocą kodu do osadzenia.

Utwórz niestandardowy element kodu w tekście sformatowanym i skopiuj i wklej „<div id="toc" class="toc"></div>" w polu kodu.


Jeśli chcesz mieć wbudowane ToC tylko dla niektórych elementów CMS i „normalne” ToC dla innych, musisz wykonać kilka dodatkowych sztuczek:

1. Utwórz selektor opcji z tylko jedną opcją: „.getElementById('content'). Wybierz go w tych elementach CMS, w których chcesz umieścić ToC w tekście sformatowanym.

2. Wyświetlaj „normalny” ToC tylko wtedy, gdy selektor nie jest ustawiony.


3. Dodaj wartość selektora do następnej części kodu. Teraz, jeśli selektor został wybrany, kod dołączy elementy ToC w poprawnym div ToC.

Unikaj nakładki paska nawigacyjnego podczas przewijania

Możesz zauważyć, że po kliknięciu łącza do spisu treści strona przewija się w dół do właściwego nagłówka, ale zostaje zablokowana przez pasek nawigacyjny.

Aby to naprawić:

  1. Upewnij się, że pozycja elementu nawigacyjnego jest ustawiona na „stałą”
  2. Zmień tag elementu nav na „Nagłówek”

Kąt

Otóż ​​to! Jeśli napotkasz jakieś problemy po drodze, nie wahaj się wysłać mi e-maila lub skontaktować się przez Twitter / LinkedIn.

Chciałabym również wiedzieć, czy w końcu korzystasz z tego systemu, więc proszę, napisz do mnie, jeśli tak, i udostępnij wpis komuś innemu, kto może z niego skorzystać ️