본문 바로가기
프론트엔드/블로그

티스토리 목차를 만들어보자!

야생에서 온 하프 입니다 😊

제가 사용하고 있는 목차를 같이 만들어 봅시다.

제목1, 제목3 으로만 반응하도록 했습니다.

이유는.. 제목1과 제목2는 크게 차이가 나지 않아서 구분이 잘 안되더라구요..

필요하실 때 커스텀 하시면 될 듯 합니다.

 

📝 목차

목차 구성 조사

1. jquery.toc.js

제가 목차를 만들기 위해서 찾아보았을 때는, jquery.toc.js가 많이 보였습니다.

그래서 이것이 무엇인지는 알고 사용은 해야겠다 싶었습니다.

jquery.toc.js는 HTML 문서에 있는 h1, h2 등의 태그들을 목차로 만들어주는 jquery의 플로그인 입니다.

jquery.toc.js는 여기에서 다운받으실 수 있습니다.

일단 어떻게 만들면 좋을지 잘 모르겠어서 해당 블로그를 참고 했습니다.

서식 추가에서 제가 적용 했던 코드는 다음과 같습니다.

<script>
  $(document).ready(function () {
    var $toc = $("#toc");
    $toc.toc({ content: ".tt_article_useless_p_margin", headings: "h2, h3, h4" });
  });
</script>

<div class="book-toc" style="margin-top: 20px; margin-bottom: 30px;">
  <p data-ke-size="size16">목차</p>
  <ul id="toc"></ul>
</div>

 

대망의!!.. 결과를 !

 

오호호 잘되는거 같군요!!..

(사실 필자는 전부터 계속 시도해보았지만 되지 않았었고.. 몇시간뒤 해보니 되던.. 알 수 없는 html의 세계)

자아 됐으니 코드가 어떻게 구성이 되어있는지 봅시다!

 

 

아닛.. 무언가.. 고쳐야할게 겁나게 많아 보이는데,, 🫢

게다가 필자는 h2와 h4만 쓰니.. 고민이 많이 되는 상황!!..

결국 쓰지 않기로 하였다. 🥹


2. dom제어

dom을 직접 제어해서 html에 바로 때려박기! 를 해보겠습니다.

관련 글은 안보이는구만요

그러니 필자가 직접 만들었다죠!! 😀

사실 jquery를 싫어하는것도 한 몫 합니다ㅋㅋ~

제가 사용했던건 document.querySelectordocument.createElement를 사용 했습니다.

 

const onLoad = () => {
    let title = document.querySelectorAll(".tt_article_useless_p_margin h2, .tt_article_useless_p_margin h4")
    let container = document.querySelector(".index-contents");

    for(let i = 0; i < title.length; i ++) {
      let ranStr = "g" + Math.random().toString(36).substring(2, 11);
      let tagName = title[i].tagName;
      let contetns = title[i].textContent;

      let div = document.createElement("div");
      //div.id = ranStr;
      title[i].id = ranStr;
      div.onclick = scrollMove(ranStr);

      if(tagName === "H2") {
            div.className = "index-big-title";
          div.innerText = "🌳" + contetns;
      } else {
          div.className = "index-small-title";
          div.innerText = "🌿 " + contetns;
      }
      container.append(div);
    }
  }
  window.addEventListener("load", onLoad);

 

핵심적인 기능 위주로만 설명드리겠습니다.

2번 줄 : window.addEventListener를 사용해 페이지가 로드가 되면, 글 내부에 있는 h2와 h4 태그를 전부 찾습니다.

6번 줄 : 목차에서 각각의 요소를 클릭하게 되면 해당 부분으로 이동할 수 있도록 랜덤으로 id를 부여 합니다.

- 숫자로 시작하면, querySelector가 동작하지 않기에.. 문자열로 시작할 수 있도록 했습니다.

10번 줄 : document.createElement를 통해 div의 빈 태그를 생성 합니다.

- 만들어진 div 태그에 onclick이벤트와 className, text를 지정하기 위해 만들어졌습니다.

13번 줄 : 클릭했을 시 scrollMove 함수로 전달 합니다.

15번 줄 : h2태그인지 h4태그인지 비교하여, css를 지정 합니다.

 

 

13번 줄에서 나왔던 scrollMove 함수를 살펴보겠습니다!.

 const scrollMove = (ranStr) => { // 클로저
     return () => {
       let target = document.querySelector("#" + ranStr);
       if(target) {
             target.scrollIntoView({ behavior : 'smooth'})
       }
     }
  }

 

scrollMove 함수로 ranStr을 넘겨줘야 하는 입장이라서, 클로저를 통해 ranStr을 넘겨줄 수 있도록 설정했습니다.

그리고 해당 부분을 클릭했을 때는 scrollIntoView를 사용해서 스무스!! 하게 이동할 수 있습니다.

 


적용 방법

1. 서식 등록

우선 서식을 등록하기 위해서 찾아보면 많은~ 정보들이 있지만 다시한번.. 알려드리겠습니다.

 

관리자에서 콘텐츠 -> 서식관리를 누릅니다. 

 

 

서식쓰기를 클릭합니다.

 

 

아래의 코드를 붙여넣기 합니다.

<script>
  const scrollMove = (ranStr) => { // 클로저
     return () => {
       let target = document.querySelector("#" + ranStr);
       if(target) {
         	target.scrollIntoView({ behavior : 'smooth'})
       }
     }
  }
  
  const onLoad = () => {
    let title = document.querySelectorAll(".entry-content h2,h4")
	let container = document.querySelector(".index-contents");
    
    for(let i = 0; i < title.length; i ++) {
      let ranStr = "g" + Math.random().toString(36).substring(2, 11);
      let tagName = title[i].tagName;
      let contetns = title[i].textContent;
      
      let div = document.createElement("div");
      //div.id = ranStr;
      title[i].id = ranStr;
      div.onclick = scrollMove(ranStr);
      
      if(tagName === "H2") {
      	  div.className = "index-big-title";
          div.innerText = "🌳" + contetns;
      } else {
          div.className = "index-small-title";
          div.innerText = "🌿 " + contetns;
      }
      container.append(div);
    }
  }
  window.addEventListener("load", onLoad);
  
</script>
<div id="index-container">
<div class="index-title">📝 목차</div>
<div class="index-contents">​</div>
</div>

 

 

목차 CSS를 복사해서 html 편집에서 CSS를 넣도록 합니다!

#index-container {
  border: 1px solid lightgray;
  margin: 0 auto;
  width: 80%;
  background-color: #F5F5F5;
  border-radius: 5px;
  overflow: hidden;
}

.index-title {
  font-weight: bold;
  color: black;
  width: 100%;
  padding: 10px;
  background-color: #E8E2E2;
}

.index-contents {
  padding: 10px;
}

.index-contents div {
  height: 30px;
  line-height: 30px;
  width: 100%;
  cursor: pointer;
}

.index-contents div:hover {
  background-color: #FAFAFA;
}

.index-big-title {
  padding-left: 10px; 
}

.index-small-title {
  padding-left: 40px; 
}

 

 


그러면 이러한 결과물을 얻으실 수 있을 겁니다!