🎁 Index
내가 쓴 포스팅을 가끔 참고할 일이 생긴다.
원하는 부분만 슥삭쇽 찾아서 보고싶은데, 포스팅이 길다보니 계속 스크롤을 내려서 찾아줘야 했다.
벨로그는 자동으로 목차를 생성해주는 것 같던데...
목 마른 자가 우물 판다고 바로 만들어보았다😀
⛏️ 목표는 이런 목차를 만드는 거였다.
- 포스트 옆 오른쪽 상단 빈 영역에 목차가 생긴다.
- 스크롤을 내려도 목차는 같은 위치에 고정되어 있다.
- 페이지가 너무 좁거나 스크롤이 포스트 영역을 벗어나면 목차는 나타나지 않는다.
- 제목1, 제목2에 대해 목차가 생긴다.
- 목차를 누르면 해당 소제목으로 스크롤이 이동한다.
- 스크롤을 내리면 목차에서 내가 현재 위치하고 있는 소제목에 강조 효과가 생긴다.
👉 목차 영역 생성
HTML
목차로 만들어줄 #index를 생성한다.
#index 안에는 .item이 소제목으로 들어간다.
<s_permalink_article_rep>
<div id="index">
</div>
...
CSS
slideToggle()을 통해 동작할 것이므로 display 속성을 none으로 설정해준다.
#index {
display: none;
position: fixed;
width: 180px;
max-height: 300px;
top: 60px;
right: 20px;
z-index: 999;
border-left: 2px solid #eee;
padding-left: 12px;
overflow: scroll;
}
브라우저 크기가 작아지면 가독성을 위해 목차는 아예 보이지 않아야 한다.
스킨의 포스트 영역 크기에 따라 재량껏 선택해준다.
@media screen and (max-width:1279px) {
.index { display: none !important; }
}
제목2 즉 h3에는 sub 클래스를 추가해 제목1과 차별화할 것이다.
sub 클래스의 스타일을 정의해주자.
#index .item {
height: 20px;
font-size: 12px;
color: #555;
line-height : 20px;
padding-left: 4px;
padding-right: 8px;
cursor: pointer;
white-space: nowrap;
overflow:hidden;
text-overflow: ellipsis;
}
#index .item.sub {
padding-left: 12px;
}
현재 위치하고 있는 소제목에는 selected 클래스를 추가해 강조 효과를 줄 것이다.
selected 클래스의 스타일도 정의해준다.
#index .selected {
font-size: 13px;
font-weight: 500;
padding-left: 0px;
color: #222;
transition: 0.2s ease !important;
}
#index .sub.selected {
padding-left: 4px;
}
👉 목차 요소 생성
게시글에서 제목1, 제목2에 해당하는 텍스트들을 목차로 만들어줄 것이다.
티스토리에서는 h2, h3 태그가 이에 해당한다.
각각의 소제목을 클릭하면 해당 위치로 이동하는 클릭 이벤트를 넣어주었다.
$('.entry-content h2, .entry-content h3').each(function (index, item) {
var offset = $(this).offset(); // 요소 위치 좌표
var text = $(this).html().replace(/\<b\>|\<\/b\>/gm, ""); // 소제목 텍스트
var div = $("<div class='item'>"+text+"</div>").on("click", function() {
$('html').animate({scrollTop : offset.top}, 0);
});
if($(this).prop('tagName')=="H3") {
div.addClass("sub");
}
$("#index").append(div);
});
👉 페이지 로드
처음 페이지가 로드되면, 스크롤의 위치가 포스트 영역에 있는지 판단해 목차를 보여줄지 말지 결정해야 한다.
또한 목차를 보여준다면 어떤 소제목에 강조 효과를 줄지 판단해야 한다.
var isToggle = false; // 토글이 열렸는지 닫혔는지 나타내는 변수
var before = 0; // 마지막 스크롤 직전의 스크롤 위치
var after = 0; // 마지막 스크롤 후의 스크롤 위치
// 포스트 영역 내에 있으면 목차를 보여준다
if ($('html').scrollTop>$(".entry-content").offset().top && $('html').scrollTop<$(".comment-form").offset().top-200) {
$("#index").slideToggle(300);
isToggle = true;
// 현재 스크롤 위치에 해당하는 소제목을 찾고 그 소제목에 강조효과를 준다
$('.entry-content h2, .entry-content h3').each(function (index, item) {
var pos = document.documentElement.scrollTop;
var offset = $(this).offset().top;
if(pos+100>=offset) {
before = index;
}
});
$("#index .item").removeClass("selected");
$("#index .item").eq(before).addClass("selected");
}
👉 스크롤 이벤트
스크롤이 발생하면 목차 보여주기 여부, 소제목 강조 여부, 목차 스크롤 여부를 결정한다.
자세한 사항은 각주를 통해 정리했다.
// 스크롤시
window.addEventListener('scroll', () => {
var pos = document.documentElement.scrollTop;
var after = 0;
// 스크롤 위치가 포스트 영역 내에 있을 경우
if(pos>$(".entry-content").offset().top && pos<$(".comment-form").offset().top-200) {
if(!isToggle) {
$("#index").slideToggle(300);
isToggle = true;
}
$('.entry-content h2, .entry-content h3').each(function (index, item) {
if(pos+100>=$(this).offset().top) {
after = index;
}
});
if(before!=after) {
// 목차 소제목 강조효과 재설정
$("#index .item").removeClass("selected");
$("#index .item").eq(after).addClass("selected");
// 목차 내에 스크롤이 있는 경우 목차 이동에 따라 자연스럽게 스크롤도 내려줌줌
if(after/$("#index .item").length<=0.25) {
$("#index").animate({scrollTop : 0}, 200);
} else if(after/$("#index .item").length>=0.75) {
$("#index").animate({scrollTop : 280}, 200);
} else {
$("#index").animate({scrollTop : 280*after/$("#index .item").length}, 200);
}
before = after;
}
// 스크롤 위치가 포스트 영역 밖에 있을 경우
} else {
if(isToggle) {
$("#index").slideToggle(300);
isToggle = false;
}
}
});
🐰
결과적으로 이렇게 예쁜 목차가 완성됐다❣️
포스팅 가독성에 큰 도움이 될 것 같다🥰