최근에 끈적한 목차에 활성 상태를 추가할 수 있게 되었습니다. 지침은 기사 끝을 참조하세요!
배경
Flowrite에서 우리는 최근 더 긴 콘텐츠를 쓰기 시작했고 가장 기본적인 요소인 목차부터 시작하여 블로그를 더 읽기 쉽게 만들고 싶었습니다.
우리는 Webflow를 사용하고 있고 그것을 절대적으로 좋아하지만 CMS 항목에 대해 확장 가능한 ToC를 만드는 것이 그렇게 간단하지 않다는 것이 밝혀졌습니다. 기존의 모든 솔루션은 ID와 링크를 수동으로 설정하거나 타사 플러그인을 사용합니다.
우리는 블로그의 제목을 기반으로 목차를 자동으로 생성하는 간단한 시스템을 원했습니다. 그것이 우리가 구축한 것이며, 여기 당신도 똑같이 할 수 있는 방법이 있습니다!
어떻게 작동합니까?
목차 항목을 디자인하십시오. 원하는 대로 만들 수 있습니다. 호버 상태, 애니메이션 등을 만듭니다.
CMS 페이지의 아무 곳에서나 특정 ID로 ToC용 div를 만듭니다.
CMS 페이지의 <body> 태그 끝에 코드를 삽입합니다.
ToC는 각 CMS 항목에 대해 자동으로 생성됩니다.
동적 목차 만들기
목차 항목 디자인
ToC 항목에 클래스를 지정하고(우리는 "tocitem"을 사용함) 원하는 방식으로 스타일을 지정합니다.
내 권장 사항은 이러한 요소를 디자인하기 위해 별도의 개인 페이지를 사용하는 것입니다. 이렇게 하면 나중에 필요한 경우 디자인을 쉽게 수정할 수 있습니다.
우리는 Notion의 목차 요소의 단순함이 마음에 들었으므로 이를 벤치마크로 사용했습니다.
하나 이상의 제목 유형을 포함하려면 추가 클래스("toc-h2", "toc-h3" 등)를 지정해야 합니다.
목차에 대한 요소 만들기
ToC를 원하는 곳에 div를 추가하고 ID를 "toc"로 지정합니다. 다시 말하지만 이 요소의 스타일을 원하는 대로 지정할 수 있습니다.
️
서식 있는 텍스트 요소 안에 목차를 포함하려면 이 문서의 끝 부분에서 자세한 내용을 참조하세요.
마지막으로 서식 있는 텍스트 요소에 id "content"를 지정합니다. 이것은 나중에 목차에서 올바른 제목을 사용하는지 확인하는 데 필요합니다.
두 가지 옵션 중에서 선택
ToC는 자동으로 생성되므로 포함할 제목을 지정해야 합니다. 이 게시물에서는 두 가지 옵션을 다룹니다.
단일 정적 제목 유형(예: H2)만을 기반으로 목차 생성.
선택한 여러 제목을 기반으로 ToC 생성(예: 한 블로그 게시물에 대한 H2 및 H3, 다른 블로그 게시물에 대한 H2 및 H4).
옵션 1: 단일 제목 목차
이 옵션에서 ToC는 항상 동일한 제목을 기반으로 생성됩니다.
컬렉션 페이지의 <body> 태그 끝에 다음 코드를 삽입하세요. 작동 방식을 이해하려면 각 줄 끝에 있는 주석을 참조하세요.
<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>
사이트를 게시하면 됩니다.
옵션 2: 다중 제목 목차
이 옵션을 사용하면 ToC를 생성하는 데 사용할 제목을 사례별로 결정할 수 있습니다.
컬렉션에 새 텍스트 필드를 만드는 것으로 시작해 보겠습니다. 우리는 그것을 "...에 기반한 목차"라고 부릅니다. 여기에서 각 CMS 항목의 목차에 사용할 제목을 지정합니다. 쉼표로 구분하고 공백을 포함하지 마십시오.
이제 컬렉션 페이지의 <body> 태그 끝에 다음 코드를 삽입합니다. 작동 방식을 이해하려면 각 줄 끝에 있는 주석을 참조하세요.
<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>
마지막으로 [HEADINGS]를 "ToC based on..." CMS 필드 값으로 대체해야 합니다.
이제 게시할 준비가 되었습니다.
커스터마이징
고정 목차의 활성 상태
CSS-Tricks에 대한 Chris Coyier의 게시물에서 영감을 받아 우리는 가시적인 ToC 항목에 활성 상태를 추가하는 방법을 구축했습니다. 이는 끈적한 ToC를 위한 훌륭한 기능입니다.
먼저 "observer.observer(heading);"를 추가합니다. 이전에 구현한 코드 시작 부분에 정확한 위치는 스크린샷을 참조하세요.