구글 블로그(블로그 스팟) 자동 목차 생성하기

매번 글을 발행할 때마다 수동으로 목차를 만드는 것은 번거로운 일입니다. 그래서 블로그스팟 게시물에 자동으로 목차를 생성해주는 자바스크립트 코드와 이를 꾸며주는 CSS 스타일을 소개하고, 적용하는 방법을 알려드리겠습니다.


⚠️ 먼저, 자바스크립트 코드가 작동하기 위해서는 jQuery 3.6.0이 필요합니다. 이를 설치하기 위해 코드 한 줄만 삽입하면 됩니다. 다음 글에서 꼭 먼저 확인하고 오세요.

왜 자동 목차를 사용해야 할까요?

  1. 가독성 향상: 독자들이 글의 전체 흐름을 빠르게 파악하고 필요한 부분만 골라 읽을 수 있습니다.
  2. 사용자 경험 증진: 긴 글에서도 원하는 정보로 쉽게 이동할 수 있어 편리합니다.
  3. 전문적인 인상: 잘 정리된 목차는 블로그를 더욱 전문적으로 보이게 합니다.
  4. 시간 절약: 매번 수동으로 목차를 만들 필요 없이 자동으로 생성됩니다.

자동 목차 코드 소개

자동 목차 기능은 크게 두 부분으로 나뉩니다.

  1. 자바스크립트(JavaScript): 글 본문에서 지정된 제목 태그(기본값 H2)를 찾아 목차 목록을 만들고, 각 항목에 해당 제목으로 이동하는 링크를 생성합니다. 목차를 표시하거나 숨기는 기능도 포함되어 있습니다.
  2. CSS(Cascading Style Sheets): 생성된 목차의 디자인(배경, 테두리, 글꼴, 색상, 간격 등)을 보기 좋게 꾸며줍니다.
아래 코드들은 Essential 테마 기준으로 만들어졌습니다. 다른 테마에서도 적용 가능할지는 잘 모르겠습니다. 또한, ChatGPTGrok을 사용하여 작성하였습니다.

1. 자바스크립트 코드

이 코드는 게시물 페이지(isSingleItem)에서만 작동하도록 설정되어 있으며, 본문 내 제목 태그를 분석하여 목차를 동적으로 생성합니다. </body>태그 바로 위에 삽입하세요.

<!--자동 목차 시작-->
<b:if cond='data:view.isSingleItem'>
<script>
  //<![CDATA[
var toc_options={target:["h2"],autoNumber:false,condTargetCount:3,showToc:true,width:"100%",marginTop:"2em",marginBottom:"3em",indent:"10px",postBodySelector:".widget.Blog"};(function(i){var j=0;document.addEventListener("DOMContentLoaded",function(){var p=document.querySelector(toc_options.postBodySelector);if(p==null||typeof p==="undefined")return;if(toc_options.target.length==0)return;var rootContent=h(toc_options,p);if(rootContent.children.length>=toc_options.condTargetCount){var q=c(rootContent);o(q);}});function h(q,p){var u=q.target.length;var t=function(E,D,w){var z=q.target[E];var x=E<u-1?q.target[E+1]:"";var y="section-"+(j++);var F=g(z,m(D),E+1,y);w.children.push(F);D.id=y;var A=f(D);if(x==="")return;while(true){if(A==null||typeof A==="undefined")break;if(b(A)==z)break;if(b(A)==x){t(E+1,A,F);}else{var B=A.getElementsByTagName(x);for(var C=0;C<B.length;C++){t(E+1,B[C],F);}}A=f(A);}};var r=g("ROOT","",0);var v=p.getElementsByTagName(q.target[0]);for(var s=0;s<v.length;s++){t(0,v[s],r,"");}return r;}function c(s){var r=document.createElement("div");r.classList.add("b-toc-container");r.style.marginTop=toc_options.marginTop;r.style.marginBottom=toc_options.marginBottom;toc_options.width==="100%"?r.style.display="block":r.style.width=toc_options.width;var q=document.createElement("p"),w=document.createElement("span"),v=document.createElement("span"),u=document.createElement("span");v.classList.add("b-toc-show-wrap");u.classList.add("b-toc-show-wrap");var y=document.createElement("a");w.innerText="Contents";y.href="javascript:void(0);";q.appendChild(w);q.appendChild(v);q.appendChild(y);q.appendChild(u);var t=function(z){var p=typeof z==="boolean"?z:e(r,"hide");if(p){y.innerText="hide";r.classList.remove("hide");}else{y.innerText="Show";r.classList.add("hide");}};y.addEventListener("click",t);t(toc_options.showToc);var x=document.createElement("ul");s.children.forEach(function(z,p){n(x,z,(p+1)+"");});r.appendChild(q);r.appendChild(x);return r;}function n(s,u,w){var p=document.createElement("li"),q=document.createElement("a");p.style.paddingLeft=toc_options.indent;q.href="#"+u.id;if(toc_options.autoNumber){var t=document.createElement("span");t.classList.add("toc-number");t.innerText=w;}var v=document.createElement("span");v.classList.add("toc-text");v.innerText=u.text;if(toc_options.autoNumber)q.appendChild(t);q.appendChild(v);p.appendChild(q);s.appendChild(p);if(u.children.length>0){var r=document.createElement("ul");p.appendChild(r);u.children.forEach(function(y,x){n(r,y,w+"-"+(x+1));});}}function o(q){var p=document.querySelector(toc_options.postBodySelector);if(!p)return;var elements=p.querySelectorAll("table, p, "+toc_options.target[0]);if(elements.length===0){k(p,q);return;}var firstElement=elements[0];k(firstElement,q);}function g(q,r,p,s){return {tagName:q,text:r,children:[],nestLevel:p,id:s};}function m(p){return p.innerText;}function f(p){return p.nextElementSibling;}function d(p){return p.previousElementSibling;}function b(p){return p.tagName.toLowerCase();}function e(p,q){return p.classList.contains(q);}function l(p){return p.parentNode;}function a(q,s){var r=l(q),p=f(q);if(r!=null&&p!=null){r.insertBefore(s,p);}}function k(p,r){var q=l(p);if(q!=null){q.insertBefore(r,p);}}})(window);//]]>
</script>
</b:if>
<!--자동 목차 끝-->

주요 설정 옵션 (toc_options)

코드 상단의 toc_options 객체에서 몇 가지 설정을 변경할 수 있습니다.

  • target:["h2"]: 목차를 생성할 제목 태그를 지정합니다. 예를 들어 H2와 H3 태그를 모두 포함하려면 ["h2", "h3"] 로 변경합니다.
  • autoNumber:false: 목차 항목 앞에 번호(예: 1., 1.1, 2.)를 자동으로 붙일지 여부를 결정합니다. true로 설정하면 번호가 표시됩니다.
  • condTargetCount:3: 지정된 제목 태그가 이 숫자 이상일 때만 목차를 표시합니다. 짧은 글에는 목차가 불필요할 수 있으므로 이 옵션으로 조절할 수 있습니다.
  • showToc:true: 페이지 로드 시 목차를 기본적으로 보여줄지(true), 숨길지(false) 결정합니다.
  • width:"100%": 목차 컨테이너의 너비를 지정합니다. CSS로도 제어 가능합니다.
  • marginTop:"2em", marginBottom:"3em": 목차 위아래 여백을 지정합니다.
  • indent:"10px": 하위 목차 항목의 들여쓰기 간격을 지정합니다.
  • postBodySelector:".widget.Blog": (중요!) 목차를 생성할 기준이 되는 글 본문 영역을 선택하는 CSS 선택자입니다. 대부분의 블로그스팟 테마에서는 .widget.Blog 또는 .post-body 등을 사용하지만, 사용 중인 테마에 따라 이 값이 다를 수 있습니다. 만약 목차가 제대로 생성되지 않는다면, 개발자 도구(F12)를 이용해 실제 글 본문 영역의 클래스(class)나 아이디(id)를 확인하고 이 값을 수정해야 할 수 있습니다.

2. CSS 코드

이 CSS 코드는 위 자바스크립트로 생성된 목차의 디자인을 담당합니다. 

]]></b:skin> 바로 위에 삽입하세요.

/* 자동 목차 시작 */
.b-toc-container {
  position: relative;
  background: #f9f9f9;
  border: 1px solid #ddd;
  border-radius: 10px;
  display: block;
  padding: 1.2em;
  margin: 1.5em auto;
  box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.1);
  width: 70%;
}

.b-toc-container p {
  text-align: center;
  margin: 0;
  font-weight: bold;
  font-size: 1.2em; /* 글자 크기 줄임 */
  color: #333;
}

.b-toc-container ul {
  list-style: none;
  margin: 0.8em 0 0;
  padding: 0;
  counter-reset: toc-counter;
}

.b-toc-container.hide > ul {
  display: none;
}

.b-toc-container ul li {
  margin: 0.3em 0; /* 항목 간 간격 조정 */
  padding-left: 2em; /* 점과 텍스트 사이 간격 증가 */
  position: relative;
  font-size: 1em; /* 글자 크기 조정 */
  color: #444;
  transition: all 0.3s ease;
  list-style: none;
  display: flex;
  align-items: center;
}

.b-toc-container ul li::before {
  content: "\2022";
  font-size: 1.5em; /* 점 크기 줄임 */
  color: #42a5f5;
  position: absolute;
  left: 5px; /* 점 위치 조정 */
  top: 50%;
  transform: translateY(-50%); /* 점을 텍스트와 수직 정렬 */
  font-weight: bold;
}

.b-toc-container ul li a {
  color: #2c3e50;
  text-decoration: none;
  display: inline-block;
  transition: color 0.3s ease;
  margin-left: 10px; /* 점과 텍스트 간격 증가 */
}

.b-toc-container ul li a:hover {
  color: #42a5f5;
}

/* 표시/비표시 버튼 */
.b-toc-container p a {
  position: absolute;
  right: 12px;
  top: 12px;
  font-size: 0.75em;
  color: #555;
  background: #e0e0e0;
  border-radius: 5px;
  padding: 4px 8px;
  text-decoration: none;
  transition: background 0.3s ease, color 0.3s ease;
}
.b-toc-container p a:hover {
  background: #42a5f5;
  color: #fff;
}
/* 작은 화면에서 본문과 동일한 폭 유지 */
@media (max-width: 768px) {
  .b-toc-container {
    width: 100%;
    max-width: 90%; /* 본문 텍스트 폭과 최대한 일치 */
    padding-left: 5%; /* 본문 패딩과 동일하게 설정 */
    padding-right: 5%;
  }
}
/* 자동 목차 끝 */

CSS 코드에서는 목차 상자의 배경색, 테두리, 그림자, 너비, 여백, 글꼴 크기, 색상 등을 자유롭게 수정하여 블로그 디자인과 어울리게 변경할 수 있습니다. 주석을 참고하여 원하는 부분을 수정해 보세요.

블로그스팟 테마에 적용하는 방법

이제 이 코드들을 여러분의 블로그스팟 테마에 적용해 보겠습니다. 주의: 테마 HTML을 수정하기 전에는 반드시 기존 테마를 백업해두세요! (테마 > 내 테마 옆 점 3개 > 백업)

  1. 블로그스팟 관리자 페이지로 이동합니다.
  2. 왼쪽 메뉴에서 테마를 클릭합니다.
  3. 맞춤설정 버튼 옆의 아래 화살표(▼)를 클릭하고 HTML 편집을 선택합니다.
  4. CSS 코드 적용:
    • HTML 편집기 안에서 Ctrl + F (Mac에서는 Cmd + F)를 눌러 ]]></b:skin> 를 검색합니다.
    • 찾은 ]]></b:skin> 바로 위에 위에 제공된 CSS 코드 전체 (/* 자동 목차 시작 */ 부터 /* 자동 목차 끝 */ 까지)를 복사하여 붙여넣습니다.
  5. 자바스크립트 코드 적용:
    • HTML 편집기 안에서 Ctrl + F (Mac에서는 Cmd + F)를 눌러 </body> 를 검색합니다.
    • 찾은 </body> 태그 바로 위에 위에 제공된 자바스크립트 코드 전체 (<!--자동 목차 시작--> 부터 <!--자동 목차 끝--> 까지)를 복사하여 붙여넣습니다.
  6. 오른쪽 상단의 저장 아이콘(💾)을 클릭하여 변경사항을 저장합니다.
  7. 확인: 블로그로 돌아가서 제목 태그(기본 설정 H2)가 3개 이상 있는 게시물을 열어 목차가 제대로 생성되고 작동하는지 확인합니다. 목차 링크를 클릭했을 때 해당 제목으로 잘 이동하는지도 테스트해보세요.

문제 해결 팁

  • 목차가 나타나지 않아요:
    • 게시물에 toc_optionstarget에 지정된 제목 태그(예: H2)가 condTargetCount에 설정된 개수 이상 있는지 확인하세요.
    • 자바스크립트 코드의 postBodySelector 값이 현재 사용 중인 테마의 본문 영역 선택자와 일치하는지 확인하세요. (개발자 도구 F12 활용)
    • 자바스크립트 코드가 </body> 태그 바로 위에, CSS 코드가 </head> 태그 바로 위에 제대로 복사되었는지 확인하세요.
    • 자바스크립트 코드 앞뒤의 <!--자동 목차 시작-->, <!--자동 목차 끝--> 주석과 <b:if>, <script> 태그들이 모두 포함되었는지 확인하세요.
  • 목차 스타일이 이상해요:
    • 다른 CSS 코드와 충돌이 있을 수 있습니다. CSS 코드의 선택자 우선순위를 높이거나 (예: #main .b-toc-container) 충돌하는 기존 스타일을 수정해야 할 수 있습니다.
이 글의 목차
    면책: 이 글은 개인적 의견을 담은 정보 제공용 기록이며 투자 조언 또는 투자 권유가 아닙니다.
    링크가 복사되었습니다.