일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- 보안 그룹
- Unchecked Exception
- java
- 이펙티브 자바
- https
- 생각정리
- 바이트코드
- 자바
- ec2
- springboot
- 파라미터 그룹
- try-with-reources
- 자바스터디
- Effective Java
- RDS
- spring-security
- JVM
- 피리티어
- AWS
- Spring
- 예외
- Final
- 이펙티브자바
- bytecode
- Checked Exception
- Annotation
- exception
- error
- Today
- Total
개발 일지
글에 내용을 한눈에 볼 수 있는 목차가 우측에 있었으면 해서 알아보던 중에 괜찮은 라이브러리가 있어서 오늘은 티스토리에 자동으로 목차를 띄우게 해 보려고 합니다.
+ 티스트리를 커스텀하기 위해서는 HTML 코드와 CSS 코드를 수정해야 합니다.
코드를 수정하는 방법은 블로그 관리 > 스킨 편집 > html 편집
으로 들어가면 됩니다


0. 사용할 라이브러리
https://github.com/tscanlin/tocbothttps://tscanlin.github.io/tocbot/
Tocbot
Tocbot builds a table of contents (TOC) from headings in an HTML document. This is useful for documentation websites or long markdown pages because it makes them easier to navigate. This library was inspired by Tocify, the main difference is that Tocbot us
tscanlin.github.io
tocbot이라는 라이브러리를 사용해서 목차를 생성해 보도록 하겠습니다.
1. HTML 편집
아래 코드를 html <head> 태그 안에 넣어줍니다.
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tocbot/4.11.1/tocbot.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/tocbot/4.11.1/tocbot.min.js"></script>
다음으론 목차를 넣을 부분에 toc 태그를 넣어줘야 합니다. 저는 CMain태그 아래에 넣었습니다. 구조로 보면 우측과 같습니다.


이제 자바스크립트를 넣어줍니다. 자바스크립트 코드는 <body> 태그 안, 맨 끝에 넣어주시면 됩니다(</body> 바로 위에)
<script>
// '.area_view'대신 본인한테 맞는 클래스 값으로 변경필요
var content = document.querySelector('.area_view')
var headings = content.querySelectorAll('h1, h2, h3, h4, h5, h6')
const headingMap = {};
Array.from(headings).forEach(heading => {
if (heading.parentElement.classList.contains('another_category')) {
heading.classList.add('another_category_heading');
} else {
var id = heading.id || heading.textContent.trim().toLowerCase()
.replace(/\s+/g, '-')
.replace(/[^\w\-]/g, '');
headingMap[id] = (headingMap[id] || 0) + 1;
heading.id = headingMap[id] > 1 ? id + '-' + headingMap[id] : id;
}
});
tocbot.init({
tocSelector: '.toc',
contentSelector: '.area_view', // '.area_view' 대신 본인한테 맞는 클래스 값으로 변경필요
headingSelector: 'h1, h2, h3, h4, h5, h6',
hasInnerContainers: false,
collapseDepth: 6,
ignoreSelector: '.another_category_heading'
});
$(document).ready(function(){
var toc = $('.toc').addClass('toc-absolute');
var tocTop = toc.parent().offset().top;
$(window).on('scroll', function() {
toc.toggleClass('toc-fixed', $(this).scrollTop() >= tocTop)
.toggleClass('toc-absolute', $(this).scrollTop() < tocTop);
});
});
</script>
이 코드는 티스토리 반응형 #2 버전 코드입니다. 모든 스킨에 그대로 적용할 수는 없고 본인의 스킨에 맞는 태그 이름으로 변경하여 사용해야 합니다. (코드의 의미가 특정 태그 영역의 요소들을 가져오는 것인데 본문 태그의 클래스 값이 각각 다르기 때문입니다.) 태그이름 확인 방법은 아래 더 보기를 참고해 주세요.
- 본문에서 개발자 창을 활성화 합니다 ( F12, Ctrl+Shift+i )
- 그러면 사진과 같이 우측에 창이 하나 띄워집니다.
- 우측 빨간 박스를 누르고 본문에 커서를 두면 해당 영역을 잡으면서 정보가 나옵니다
- 본문 테그의 클래스 정보를 얻을 수 있습니다.
본인의 스킨 태그를 알았으면 코드를 나눠서 자세히 살펴보겠습니다. (단순히 목차 만들기가 목표이신 분들은 건너 CSS로 바로 넘어가셔도 됩니다)
tocbot라이브러리가 제대로 동작하려면 id값이 있어야 링킹이 되기 때문에 id 값을 동적으로 넣어주는 과정입니다. 이 부분 없이 목차를 만들면 목차는 띄워지지만 눌러도 이동이 되지 않습니다.(티스토리는 자동으로 id값을 넣어주지 않음) 또한 id값은 유일해야 하기 때문에 중복이 발생하지 않게 처리해 주었습니다.
<script>
// .area_view 클래스를 가진 콘텐츠 영역을 선택
var content = document.querySelector('.area_view')
// 콘텐츠 영역 내의 모든 제목 요소(h1~h6)를 선택
var headings = content.querySelectorAll('h1, h2, h3, h4, h5, h6')
// 제목 중복 방지를 위한 맵 객체 선언
const headingMap = {};
// 제목 요소 순회 및 ID 생성 (
Array.from(headings).forEach(heading => {
// 만약 제목의 부모 요소가 .another_category 클래스를 포함하고 있다면
if (heading.parentElement.classList.contains('another_category')) {
// 해당 제목에 .another_category_heading 클래스를 추가 (목차에서 제외할 항목 표시)
heading.classList.add('another_category_heading');
} else {
// 제목에 ID가 존재하지 않으면 텍스트를 기반으로 ID 생성
var id = heading.id || heading.textContent.trim().toLowerCase()
.replace(/\s+/g, '-') // 공백을 하이픈(-)으로 변환
.replace(/[^\w\-]/g, ''); // 영문자, 숫자, 하이픈만 허용
// ID 중복 방지: 이미 존재하는 ID의 경우 숫자를 추가하여 고유하게 만듦
headingMap[id] = (headingMap[id] || 0) + 1;
heading.id = headingMap[id] > 1 ? id + '-' + headingMap[id] : id;
}
});
</script>
<script>
// tocbot 초기화 및 설정
tocbot.init({
tocSelector: '.toc', // 목차가 삽입될 컨테이너(.toc 클래스)
contentSelector: '.area_view', // 목차를 생성할 콘텐츠 영역 선택
headingSelector: 'h1, h2, h3, h4, h5, h6', // 목차에 포함할 제목 태그 설정
hasInnerContainers: false, // 중첩된 컨테이너를 허용하지 않음
collapseDepth: 6, // 6단계까지 목차가 열려있도록 설정
ignoreSelector: '.another_category_heading' // 해당 클래스를 가진 요소는 목차에서 제외
});
</script>
- tocbot을 실행시키는 부분입니다.
- tocbot을 init 할 때 필요한 옵션들의 값을 넣어주면 이 옵션을 바탕으로 tocbot이 목차를 만들어 줍니다.
<script>
// jQuery를 이용한 TOC(목차) 위치 고정 처리
$(document).ready(function(){
// 목차(.toc) 요소를 선택하고 초기 위치를 absolute로 설정
var toc = $('.toc').addClass('toc-absolute');
// 목차의 부모 요소의 Y 좌표 값을 저장 (문서 최상단으로부터의 거리)
var tocTop = toc.parent().offset().top;
// 스크롤 이벤트 처리
$(window).on('scroll', function() {
// 스크롤 위치가 목차의 부모 위치보다 아래로 내려가면 고정(fixed), 그렇지 않으면 절대 위치(absolute)
toc.toggleClass('toc-fixed', $(this).scrollTop() >= tocTop)
.toggleClass('toc-absolute', $(this).scrollTop() < tocTop);
});
});
</script>
- 페이지 스크롤이 발생해도 목차의 위치를 고정시키기 위한 코드입니다.
2. CSS 편집
toc 태그에 대한 CSS를 넣어보겠습니다.
/*tocbot*/
.toc-absolute {
display: flex;
position: absolute;
margin-top:70px;
}
.toc-fixed {
position: fixed;
top: 70px;
}
.toc {
right: calc((100% - 850px) / 2 - 300px);
width: 200px;
padding: 10px;
box-sizing: border-box;
max-height: 80vh;
overflow-y: auto;
}
.toc-list {
margin-top: 10px !important;
padding-bottom: 5px !important;
font-size: 0.9em;
}
.toc > .toc-list li {
margin-bottom: 10px;
}
.toc > .toc-list .toc-link::before {
margin-top: -0.45em;
align-items: center;
align-content: center;
}
.toc > .toc-list li:last-child {
margin-bottom: 0;
}
.toc-default-header {
display: none;
}
.toc > .toc-list li a {
text-decoration: none;
}
3. 리펙토링 목록
해상도에 따라 x축 스크롤이 생김 이슈 발생
화면이 작을 때는 아예 목차를 띄우기 않게 아래 CSS 밑에 코드를 추가해 줬습니다
해당코드는 1440px 이하의 화면에서. toc 요소를 숨기도록 설정하는 것입니다.
@media screen and (max-width: 1440px) {
.toc{
display:none;
}
}
스크롤을 해야 하위 목차가 생김
원래 tocbot 확장/축소 애니메이션을 지원하지만 저는 모든 목차를 한눈에 보이는 게 편해서 처음부터 펼쳐 두려고 합니다.
tocbot github에 해당 관련 옵션이 있어서 이것을 활용했습니다.
GitHub - tscanlin/tocbot: Build a table of contents from headings in an HTML document.
Build a table of contents from headings in an HTML document. - tscanlin/tocbot
github.com
// and close as you scroll to headings within them.
collapseDepth: 0,
- collapseDepth 옵션을 확인하고 html scrip 코드에서 tocbot을 init 할 때 collapseDepth : 6을 추가해 줬습니다.
<script>
tocbot.init({
collapseDepth : 6,
});
</script>
카테고리의 다른 글이 목차에 들어감
아래 이미지의 목차 맨 마지막을 보면 " ~ 카테고리의 다른 글" 이 목차로 들어가 있는 것을 볼 수 있습니다. 이 부분이 h4 태그로 되어있기 때문에 발생하는 문제인데 글과는 상관없는 내용이라 목차와 맞지 않다고 생각하여 목차에서 제거하려고 합니다.


이 또한 github에 해당 관련 옵션이 있어서 활용했습니다.
// Headings that match the ignoreSelector will be skipped.
ignoreSelector: '.js-toc-ignore',
ignoreSelector옵션은 원하는 요소를 목차에서 제거하는 옵션입니다. 하지만 여기에는 문제가 하나 있습니다. "카테고리의 다른 글"은 h4 태그 이외의 다른 속성을 가지고 있지 않기 때문에 당장 tocbot이 해당 태그를 인식할 수 있는 방법이 없습니다. 그래서 부모 태그 클래스인 "another_category"를 활용했습니다.

해당 태그의 부모(상위) 태그에 another_category 가 있다면 another_category_heading
값을 넣어주고 tocbot을 init 할 때 ignoreSelector 옵션에 . another_category_heading
값을 주었습니다.
if (heading.parentElement.classList.contains('another_category')) {
heading.classList.add('another_category_heading');
}
tocbot.init({
ignoreSelector: '.another_category_heading'
});
이렇게 하면 " ~ 카테고리의 다른 글" 을 목차에서 제거할 수 있습니다.
목차가 긴 경우에 잘리는 현상 발생
목차가 긴 글에서 목차가 화면을 벗어나면서 잘리는 이슈를 확인했습니다.
목차의 최대길이를 설정해 두고 그 길이를 벗어날 경우 스크롤이 생기게 수정했습니다.
.toc {
. . .
/* 목차가 너무 길어질 경우 스크롤 추가 */
max-height: 80vh; /* 화면 높이의 80%까지만 표시 */
overflow-y: auto; /* 수직 스크롤 자동 생성 */
}


4. 결과
여기까지 하면 목차를 띄우는 거에는 문제가 없지만 위치가 애매하다고 생각될 수 있습니다.
저의 경우 본문이 아래 설정으로 설정되어 있기 때문에 우측에 목차를 띄울 부분이 부족합니다.
.article_skin {
width: 870px;
min-height: 858px;
margin: 0 auto;
padding: 96px 42px 100px;
목차를 배치하기 위해선 두 가지 중 한 가지 방법을 사용해야 합니다.
1. 본문의 넓이(width)를 줄이고 배치한다
2. 본문의 margin을 조절하고 배치한다.
저는 2안으로 진행했습니다.


글 내부에서는 만족스러운 결과지만 블로그 메인 페이지에서 보면 글목록에서는 우측에 목차대신 빈 공간이 생깁니다. 글의 중앙을 유지하면서 목차를 만들기에는 좌측에 비해 우측만 너무 꽉 찬 느낌이고 좌측 margin을 줄이고 우측에 배치하자니 목록에서 우측 여백이 신경이 쓰입니다.
시도한 내용을 글로 정리해 두긴 하나 해당 이유 때문에 이걸 유지할지 말지는 고민이 좀 필요한 듯합니다.
'티스토리 스킨 커스텀' 카테고리의 다른 글
티스토리 꾸미기(코드 블럭, 접은글 등등) (0) | 2024.05.02 |
---|---|
티스토리 인라인 코드 커스텀(2) 인라인 코드 노션 처럼 바꾸기 (0) | 2024.05.01 |
티스토리 인라인 코드 커스텀(1) 인라인 코드 쉽게 적용하기 (0) | 2024.04.26 |
[기타] 티스토리 코드블럭 테마 변경 방법 (0) | 2022.11.08 |