Sommario dinamico su Webflow CMS – Il modo più semplice

Pubblicato: 2022-03-22
Di recente abbiamo reso possibile aggiungere stati attivi a un Sommario appiccicoso: vedere la fine dell'articolo per le istruzioni!

Sfondo

In Flowrite, abbiamo recentemente iniziato a scrivere contenuti più lunghi e volevamo rendere i nostri blog più leggibili, partendo dall'elemento più semplice: il sommario.

Stiamo usando Webflow e lo adoriamo assolutamente, ma si è scoperto che la creazione scalabile di ToC per gli elementi CMS non era così semplice. Tutte le soluzioni esistenti si basano sull'impostazione manuale di ID e collegamenti o sull'utilizzo di plug-in di terze parti.

Volevamo un sistema semplice che generasse automaticamente ToC in base alle intestazioni nei nostri blog. Questo è ciò che abbiamo costruito, ed ecco come puoi fare lo stesso!

Come funziona?

  1. Progetta i tuoi articoli ToC. Creali come preferisci: crea stati al passaggio del mouse, animazioni, ecc.
  2. Crea un div per il ToC con un ID specifico in qualsiasi punto della tua pagina CMS.
  3. Inserisci un pezzo di codice alla fine del tag <body> nella tua pagina CMS.
  4. I ToC vengono generati automaticamente per ogni articolo CMS.

Creazione del tuo sommario dinamico

Progetta i tuoi articoli ToC

Assegna una classe al tuo articolo ToC (usiamo "tocitem") e modellalo come preferisci.

La mia raccomandazione è di utilizzare una pagina privata separata per la progettazione di questi elementi. In questo modo puoi facilmente modificare il design in un secondo momento, se necessario.

Abbiamo adorato la semplicità degli elementi del sommario di Notion, quindi l'abbiamo usato come punto di riferimento.


Se desideri includere più di un solo tipo di intestazione, assicurati di assegnare loro una classe aggiuntiva ("toc-h2", "toc-h3", ecc.)

Crea l'elemento per il tuo ToC

Aggiungi un div dove vuoi che sia il tuo ToC e assegnagli un ID "toc". Ancora una volta, puoi modellare questo elemento come preferisci.

Se desideri avere il tuo ToC all'interno del tuo elemento RTF, consulta la fine di questo articolo per maggiori dettagli.

Infine, assegna all'elemento Rich Text un "contenuto" id. Ciò sarà necessario in seguito per assicurarci di utilizzare le intestazioni corrette nel ToC.

Scegli tra due opzioni

Poiché i ToC verranno generati automaticamente, dobbiamo indicare quali intestazioni vogliamo includervi. In questo post, trattiamo due opzioni:

  1. Generazione di ToC basati su un solo tipo di intestazione statica, ad esempio H2.
  2. Generazione di ToC in base a più titoli a tua scelta, ad esempio H2 e H3 per un post del blog e H2 e H4 per un altro.

Opzione 1: ToC a titolo singolo

In questa opzione, i ToC verranno sempre generati in base alla stessa intestazione.

Inserisci il codice seguente alla fine del tag <body> nelle pagine della raccolta. Vedi i commenti alla fine di ogni riga se vuoi capire come funziona.

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

Pubblica il sito e sei a posto

Opzione 2: ToC a più titoli

Questa opzione ti dà la possibilità di determinare caso per caso quali intestazioni verranno utilizzate per generare i ToC.

Iniziamo creando un nuovo campo di testo nella tua Collezione. Lo chiamiamo "TOC basato su...". Qui è dove specifichi le intestazioni che verranno utilizzate nel ToC di ogni elemento CMS. Separare con una virgola e non includere spazi.


Ora, inserisci il seguente codice alla fine del tuo tag <body> nelle tue pagine di raccolta. Vedi i commenti alla fine di ogni riga se vuoi capire come funziona.

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

Infine, assicurati di sostituire [HEADINGS] con il valore del tuo campo CMS "ToC based on...".


Ecco fatto, sei pronto per pubblicare.

Personalizzazione

Stati attivi in ​​un sommario appiccicoso

Ispirati dal post di Chris Coyier su CSS-Tricks, abbiamo creato un modo per aggiungere stati attivi agli elementi ToC visibili, un'ottima funzionalità per ToC permanenti.

Innanzitutto, aggiungi "observer.observe(heading);" all'inizio del codice che hai implementato in precedenza. Guarda lo screenshot per la posizione corretta.

Quindi, aggiungi il seguente snippet di codice sopra tutto il codice ToC esistente:

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

Il codice aggiunge una classe denominata "attiva" a un tocitem visibile e rimuove la classe quando viene visualizzato un nuovo tocitem.

Infine, assicurati di dare uno stile alla classe "attiva" assegnandole un colore di sfondo diverso, ad esempio.

Visualizza i ToC solo su alcuni degli elementi CMS

Se non desideri che un ToC appaia su alcuni dei tuoi articoli CMS, completa i seguenti passaggi:

‍ 1. Lascia vuoto il campo "ToC based on.."
Se stai utilizzando l'opzione 1, aggiungi uno switch nella tua raccolta CMS per indicare se il ToC deve essere visualizzato o meno.

2. Rendi condizionale la visibilità del tuo ToC div in base al selettore al passaggio 1.

3. Crea un'istruzione if all'inizio del frammento di codice ToC per evitare di eseguire la funzione se il campo è vuoto. Ricordarsi di chiudere con "}".

ToC all'interno del tuo elemento Rich Text

Se desideri inserire il tuo ToC all'interno del tuo elemento Rich Text, puoi replicare l'elemento div ToC con un codice di incorporamento.

Crea un elemento di codice personalizzato all'interno del tuo Rich Text e copia e incolla "<div id="toc" class="toc"></div>" nel campo del codice.


Se vuoi avere un ToC inline solo su alcuni elementi del CMS e un ToC "normale" su altri, devi fare un paio di trucchi aggiuntivi:

1. Crea un selettore di opzioni con una sola opzione: ".getElementById('content'). Selezionalo su quegli elementi CMS in cui desideri avere un ToC all'interno del Rich Text.

2. Visualizzare il ToC "normale" solo se il selettore non è impostato.


3. Aggiungere il valore del selettore alla parte successiva del codice. Ora, se il selettore è stato selezionato, il codice aggiungerà le voci ToC all'interno del div ToC corretto.

Evita la sovrapposizione della barra di navigazione durante lo scorrimento

Potresti notare che quando fai clic su un collegamento ToC, la pagina scorre fino all'intestazione corretta ma viene bloccata dalla barra di navigazione.

Per risolvere questo problema:

  1. Assicurati che la posizione del tuo elemento di navigazione sia impostata su "fisso"
  2. Cambia il tag dell'elemento di navigazione in "Intestazione"

Questo è tutto! Nel caso in cui dovessi riscontrare problemi lungo il percorso, non esitare a inviarmi un'e-mail o a contattarmi tramite Twitter / LinkedIn.

Mi piacerebbe anche sapere se finirai per utilizzare questo sistema, quindi per favore inviami un ping se lo hai fatto e condividi il post con qualcun altro che potrebbe trarne vantaggio ️