심플한 워드프레스 목차 (TOC) 스크립트 (플러그인 미사용)

Last Updated: 2024년 07월 21일 3개 댓글

워드프레스에는 다양한 무료 및 유료 목차 (TOC) 플러그인이 있습니다. 플러그인을 사용하면 워드프레스 사이트에 편리하게 목차를 표시할 수 있습니다. 목차 플러그인은 상세한 설정을 제공합니다.

무료 플러그인으로는 쉬운 목차 (Easy Table of Contents) 플러그인이 많이 사용됩니다. 이 블로그에는 Fixed TOC라는 유료 플러그인이 설치되어 있고, 제가 관리하는 일부 사이트에는 직접 만든 목차 스크립트가 적용되어 있습니다.

목차 플러그인을 사용하는 경우 편리하지만 목차 플러그인이 업데이트가 안 되고 방치되거나 플러그인 충돌이 발생하기도 합니다. 실제로 Easy Table of Contents 플러그인이 2.0.68 버전으로 업데이트된 후에 치명적인 오류가 발생하는 사이트들이 있어서 긴급히 2.0.68.1 버전으로 업데이트되었습니다.

워드프레스 쉬운 목차 플러그인 오류

심플한 워드프레스 목차 (TOC) 스크립트 (플러그인 미사용)

워드프레스 블로그에 목차를 표시하려는 경우 쉬운 목차 플러그인을 사용할 수 있습니다. 무료이면서 기능도 많습니다.

목차 플러그인은 보통 H2, H3 등의 헤딩 태그가 일정 개수(예: 2개) 이상이 있는 경우에 한하여 목차가 자동 표시되도록 설정할 수 있습니다. 보다 고급 기능을 원하는 경우, 이 블로그에서와 같이 유료 플러그인을 사용하면 스크롤 시 목차 아이콘이 붙박이로 고정되어 사용자들이 목차를 쉽게 펼쳐볼 수 있습니다.

플러그인은 편리한 방법이지만 플러그인 충돌을 일으키는 등 문제를 야기할 우려가 있습니다. 플러그인을 선호하지 않는 경우 다음과 같은 자바스크립트 코드를 사용하여 목차를 표시할 수 있습니다.

document.addEventListener("DOMContentLoaded", function() {
	function smoothScrollTo(element) {
		document.querySelector(element).scrollIntoView({ 
			behavior: 'smooth' 
		});
	}

	var toc = document.createElement('nav');
	toc.id = 'table-of-contents';
	toc.setAttribute('aria-label', '목차');
	toc.setAttribute('itemscope', '');
	toc.setAttribute('itemtype', 'https://schema.org/SiteNavigationElement');

	var tocLabel = document.createElement('div');
	tocLabel.id = 'toc-label';
	tocLabel.setAttribute('itemprop', 'name');
	tocLabel.innerText = '목차';
	toc.appendChild(tocLabel);

	var ul = document.createElement('ul');
	var counter = { h2: 0, h3: 0, h4: 0 };
	var headings = document.querySelectorAll('.entry-content h2, .entry-content h3, .entry-content h4');

	if(headings.length > 1) {
		Array.prototype.forEach.call(headings, function(heading) {
			var headingLevel = heading.tagName.toLowerCase();

			if (headingLevel === 'h2') {
				counter.h2++;
				counter.h3 = 0;
				counter.h4 = 0;
			} else if (headingLevel === 'h3') {
				counter.h3++;
				counter.h4 = 0;
			} else if (headingLevel === 'h4') {
				counter.h4++;
			}

			var sectionNumber = counter.h2 + (counter.h3 ? '-' + counter.h3 : '') + (counter.h4 ? '-' + counter.h4 : '');
			var escapedText = heading.innerText.replace(/"/g, '"');

			var anchor = document.createElement('a');
			var headingId = 'heading-' + sectionNumber;
			anchor.href = '#' + headingId;
			anchor.setAttribute('itemprop', 'url');
			anchor.innerText = sectionNumber + ' ' + heading.innerText;

			var li = document.createElement('li');
			if (headingLevel === 'h3') {
				li.classList.add('toc-h3');
			} else if (headingLevel === 'h4') {
				li.classList.add('toc-h4');
			}
			li.setAttribute('itemprop', 'name');
			li.appendChild(anchor);
			ul.appendChild(li);

			heading.id = headingId;
			heading.setAttribute('itemprop', 'name');
			heading.setAttribute('aria-label', sectionNumber + ' ' + escapedText);
		});

		toc.appendChild(ul);

		var firstHeading = document.querySelector('.entry-content h2, .entry-content h3, .entry-content h4');
		if (firstHeading) {
			firstHeading.parentNode.insertBefore(toc, firstHeading);
		}
	}

	var tocLinks = document.querySelectorAll('#table-of-contents a');
	tocLinks.forEach(function(link) {
		link.addEventListener('click', function(e) {
			e.preventDefault();
			var href = this.getAttribute('href');
			var target = document.querySelector(href);
			if (target) {
				target.setAttribute('tabindex', '-1');
				target.focus();
				smoothScrollTo(href);
			}
		});
	});
});

JS 스크립트는 다음 글을 참고하여 로드할 수 있습니다.

쉬운 방법으로 WPCode와 같은 Header & Footer Codes 플러그인을 사용하여 자스 스크립트를 푸터 영역에 로드할 수 있습니다. 그리 권장하지 않지만 쉽게 JS 코드를 추가하려는 경우 사용할 수 있습니다. WPCode를 사용하여 푸터 영역에 추가하려는 경우 <script>와 </script>를 추가하시기 바랍니다.

<script>
// JS 코드
</script>

그리고 다음과 같은 CSS 코드를 워드프레스 관리자 페이지 » 디자인 » 사용자 정의하기 » 추가 CSS에 추가하여 목차 상자의 스타일을 지정할 수 있습니다.

/* TOC */
#table-of-contents {
  background-color: #f8f9fa;
  border-radius: 10px;
  padding: 20px;
  margin-bottom: 30px;
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}

#toc-label {
  font-weight: 700;
  margin-bottom: 15px;
  font-size: 22px;
  color: #333;
  position: relative;
  display: inline-block;
   border-bottom: 4px solid #007bff;
}

#table-of-contents ul {
  list-style: none;
  padding: 0;
  margin-left: 20px;
}

#table-of-contents ul li {
  margin-bottom: 10px;
  position: relative;
}

#table-of-contents ul li a {
  color: #333;
  text-decoration: none;
  transition: color 0.3s;
}

#table-of-contents ul li a:hover {
  color: #007bff;
}

#table-of-contents ul li.toc-h3 {
  margin-left: 15px;
}

#table-of-contents ul li.toc-h4 {
  margin-left: 30px;
}

GeneratePress 테마에 적용할 경우 다음과 비슷하게 목차가 표시됩니다.

실제 목차 작동을 여기에서 확인할 수 있습니다.

스타일은 CSS로 조정하시기 바랍니다. 기본적인 CSS를 이해하시면 어느 정도 수정이 가능할 것입니다. 챗GPT나 Claude AI 등의 인공지능(AI)에게 부탁하여 원하는 스타일의 코드를 요청하는 것도 가능합니다.

사용자 정의 코드를 사용할 경우 장점

직접 코드를 만들고 유지하는 것이 쉽지 않을 수 있지만, 직접 코드를 만들어 사용할 경우 좋은 점이 몇 가지 있습니다.

  1. 커스터마이징 용이성
    • 커스텀 코드를 사용하면 디자인, 레이아웃, 기능 등 목차의 모든 측면을 사용자가 원하는 대로 제어할 수 있습니다.
    • 특정 요구 사항에 맞게 목차를 쉽게 수정하고 조정이 가능합니다.
  2. 가벼움 (경량)
    • 일반적으로 플러그인보다 가볍습니다.
    • 불필요한 기능이나 코드 없이 필요한 기능만 구현하는 것이 가능합니다.
    • 사이트 속도에 대한 영향을 최소화할 수 있습니다.
  3. 의존성 감소
    • 플러그인에 대한 의존성이 줄어듭니다.
    • 플러그인 호환성 문제나 잠재적인 보안 위험을 방지할 수 있습니다.

마치며

목차 플러그인을 사용하면 사용자들이 게시글의 구조를 쉽게 파악하고 원하는 내용으로 이동할 수 있어 사용자 경험(UX)을 개선하고 SEO(검색엔진최적화) 향상에도 도움이 됩니다.

워드프레스에서는 Easy TOC와 같은 무료 목차 플러그인을 사용할 수 있으며, 플러그인을 사용하고 싶지 않은 경우 이 글에 소개된 목차 스크립트를 사용하는 것으로 고려할 수 있습니다.

이 글에 제시된 코드는 티스토리 등에도 응용할 수 있습니다. 실제로 제 티스토리 블로그에도 상기 코드와 비슷한 스크립트를 사용하여 자동 목차를 표시하고 있습니다.

혹시 코드에 버그나 오류가 있는 경우 이 글의 댓글을 통해 알려주시면 반영하여 수정하도록 하겠습니다.

참고


3 개 댓글

Leave a Comment

  1. ChatGPT랑 Claude와 하루종일 싸워서 스크립트 목차 목록을 접고 펼치는 버튼을 추가 후 해상도 별로 접고 펼치는 기능도 추가하긴 했는데 해상도 변경 시 접고 펼치는 기능이 자동 전환이 안 된다는 옥에 티?를 감안하면 공들인 시간이 아까워서 앞으로는 그냥 쉬운 목차 대신 스크립트 목차를 사용하려고 합니다.. 그래도 보람 있는 싸움이었어요 ㅎㅎ

    응답