Blog

[티스토리 꾸미기] 스킨 편집 Step 6 - 본문 자동 목차

StudyGPT 2023. 12. 19.

개요

오디세이 본문 자동 목차 추가.

 

작업

1. HTML 수정

1) head - Script

</head> 상단에 추가

Step 2를 진행한 경우 삭제하고 아래 내용을 추가.

<head>
 ... 기존 소스 ...
  <!-- 자동 목차 삭제 (S) -->
  <script src="https://cdnjs.cloudflare.com/ajax/libs/tocbot/4.11.1/tocbot.min.js"></script>
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tocbot/4.11.1/tocbot.css">
  <!-- 자동 목차 삭제 (E) -->
  
-----------------------------------------------------------------------------------
  
  <!-- 자동 목차 추가 (S) -->
  <script src="https://code.jquery.com/jquery-3.6.4.min.js"></script>
  <!-- 자동 목차 추가 (E) -->
  
  <!-- Font Awesome CSS (S) -->
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
  <!-- Font Awesome CSS (E)-->
</head>

 

2) body - Div

class = article-view 하단에 추가.

<!-- 에디터 영역 -->
<div class="article-view">
  <!-- 자동 목차 View (S) -->
  <div id='toc'></div>
  <!-- 자동 목차 View (E) -->
</div>

3) Body - Script

</body> 상단에 추가

<!-- 자동 목차 Script 삭제 (S) -->
<script>
  // set heading id
  function makeHeading(headings){
    Array.prototype.forEach.call(headings, function (heading) {
      var id = heading.id ? heading.id : heading.textContent.trim().toLowerCase() .split(' ').join('-').replace(/[\!\@\#\$\%\^\&\*\(\)\:]/ig, '')
      headingMap[id] = !isNaN(headingMap[id]) ? ++headingMap[id] : 0;
      if (headingMap[id]) { heading.id = id + '-' + headingMap[id];
      } else {
        heading.id = id; }
    });
  }
  var headingMap = {};
  var headings = document.querySelector('.article-view').querySelectorAll('h1, h2, h3');
  makeHeading(headings);
  document.addEventListener("DOMContentLoaded", function() {
    // toc addon
    tocbot.init({
      // Where to render the table of contents.
      tocSelector: '.toc',
      // Where to grab the headings to build the table of contents.
      contentSelector: '.article-view',
      // Which headings to grab inside of the contentSelector element.
      headingSelector: 'h1, h2, h3',
      // For headings inside relative or absolute positioned containers within content.
      hasInnerContainers: false
    });
  });

  $("div.toc.toc-fixed").hide(0);
  $(window).scroll(function() {
    if (Math.round( $(window).scrollTop()) > 400) {
      $("div.toc.toc-fixed").show(250);
    } else {
      $("div.toc.toc-fixed").hide(250);
    }
  });
</script>
<!-- 자동 목차 Script 삭제 (E) -->

-----------------------------------------------------------------------------------

<!-- 자동 목차 Script 추가 (S) -->
<script>
  $(document).ready(function () {
    var toc = $("#toc");
    var headings = $(".article-view h2, .article-view h3");

    if (headings.length > 1) {
      toc.append("<div class='toc-title'><i class='fas fa-list-ul'></i> 목차</div><div class='line-divider'></div><ul>");

      headings.each(function (index) {
        var heading = $(this);
        var title = heading.text();
        var slug = "toc-heading-" + index;

        heading.attr("id", slug);

        if (heading.is("h2")) {
          toc.append('<li class="toc-item"><i class="fas fa-caret-right"></i><a href="#' + slug + '">' + title + '</a></li>');
        } else if (heading.is("h3")) {
          toc.append('<li class="toc-subitem"><i class="fas fa-caret-right"></i><a href="#' + slug + '">' + title + '</a></li>');
        } else if (heading.is("h4")) {
          toc.append('<li class="toc-subitem"><i class="fas fa-caret-right"></i><a href="#' + slug + '">' + title + '</a></li>');
        } else {
          toc.append('<li class="toc-subitem"><i class="fas fa-caret-right"></i><a href="#' + slug + '">' + title + '</a></li>');
        }
      });

      toc.append("</ul>");
    } else {
      toc.hide();
    }
  });
</script>
<!-- 자동 목차 Script 추가 (E) -->
... 기존 코드 ...
</body>

 

2. CSS 수정

 /* *********************************************************************
    자동 목차 삭제
    ****************************************************************** */
.toc-absolute {
  position: absolute;
  margin-top: 165px;
}

.toc-fixed {
  position: fixed;
  top: 165px;
}

.toc {
  left: calc((100% - 720px) / 2 - 300px);
  width: 250px;
  padding: 10px;
  box-sizing: border-box;
  z-index: 0;
}

.toc-list {
  margin-top: 10px !important;
  font-size: 0.9em;
}

.toc > .toc-list li {
  margin-bottom: 10px;
}

.toc > .toc-list li:last-child {
  margin-bottom: 0;
 }

.toc > .toc-list li a {
  text-decoration: none;
}

-----------------------------------------------------------------------------------

 /* *********************************************************************
    코드 수정
    ****************************************************************** */
.article-view {
    position: relative;
    margin-bottom: 12px;
    word-break: break-word;
}

 /* *********************************************************************
    자동 목차 추가
    ****************************************************************** */
#toc {
    position: sticky;
    top: 20px;
    width: 100%;
    max-height: none;
    overflow-y: auto;
    background-color: #f0f0f0;
    border: 1px solid #ddd;
    padding: 15px;
    box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
    z-index: 1000;
    white-space: nowrap;
}

.toc-title {
    font-size: 20px;
    margin-bottom: 10px;
    display: flex;
    align-items: center;
    color: #333; /* Set title color */
}

.toc-title i {
    margin-right: 10px;
}

ul {
    list-style: none;
    margin: 0;
    padding: 0;
}

.toc-item, .toc-subitem, .toc-subitem-sub {
    margin-bottom: 5px;
    display: flex;
    align-items: center;
}

.toc-item i, .toc-subitem i, .toc-subitem-sub i {
    margin-right: 5px;
}

.toc-item a, .toc-subitem a, .toc-subitem-sub a {
    color: inherit; /* Inherit color from the parent element */
    text-decoration: none;
    display: block;
    padding: 5px 0;
    transition: color 0.3s ease;
}

.toc-item a:hover, .toc-subitem a:hover, .toc-subitem-sub a:hover {
    color: #1a73e8; /* Change color on hover */
}

.toc-item.h2 {
    font-size: 18px;
    margin-left: 10px; /* h2에 대한 들여쓰기 */
}

.toc-subitem.h3 {
    padding-left: 20px;
    font-size: 16px;
    margin-left: 20px; /* h3에 대한 들여쓰기 */
}

.toc-subitem-sub.h4 {
    padding-left: 30px;
    font-size: 16px;
    margin-left: 30px; /* h4에 대한 들여쓰기 */
}

.line-divider {
    border-top: 1px solid #ddd;
    margin: 1px 0;
}

/* h2에 대한 스타일 */
.toc-item {
    margin-left: 10px; /* 원하는 만큼의 여백을 지정합니다. */
}

/* h3에 대한 스타일 */
.toc-subitem {
    margin-left: 20px; /* 원하는 만큼의 여백을 지정합니다. */
}

/* h4에 대한 스타일 */
.toc-subitem-sub {
    margin-left: 30px; /* 원하는 만큼의 여백을 지정합니다. */
}

 

 

결과

댓글