ΛneOK v4 blog

일상의 잡다한 생각과 내용을 글 또는 사진으로 표현하는 일상 블로그입니다.

# Side Menu
  • recentPost

  • popularPost

  • Archive

  • recentComment

Study/Etc_Studying

티스토리 dynamicscrollspy.js (TOC) 적용하기

2019. 5. 25., AneOK
728x90

TOC(Table of Contents, 목차)로 티스토리에서 이 기능을 사용 하려니 몇몇개가 검색되었습니다. 수동으로 글 입력 시 작동하는 것이 다인 것 같아 인터넷을 조금 검색해보니 마침 저에게 적당한 것이 있어 지금 이 블로그에서 사용 중입니다. 밑의 더 설명...

1. 설명

기본 소스 주소 : https://www.jqueryscript.net/menu/Dynamic-jQuery-Scrollspy-Plugin-For-Bootstrap-Dynamicscrollspy-js.html

다운로드도 위 사이트에 링크되어 있습니다. 없다면 link

데모주소 : https://www.jqueryscript.net/demo/Dynamic-jQuery-Scrollspy-Plugin-For-Bootstrap-Dynamicscrollspy-js/

개발자는 'psalmody'분으로 Github가시면 됩니다.

제목에서도 있듯이 Dynamicscrollspy.js를 사용 몇몇개만 적용하도록 하여 티스토리에 맞게 수정하고 사용하고 있습니다. 같은 말을 반복한다는 느낌이...

각설하고... 위의 주소로 가서 보면 Bootstrap 의 사이트에 보이는 것과 유사하게 만든 것 같습니다. 스크롤을 내려가면 그에 해당하는 곳에 '|'가 표시되고 제가 보기에 무엇보다 좋은 점은 'H'태그에 임의의 숫자가 생성된다는 것입니다. 무엇이냐 하면 다른 것들은 'H'태그의 글이 표시되는데 이것이 약간의 오류가 있더군요. (지금은 무슨 오류인지 기억이 나질 않지만...) 그래서 이 기능을 넣었던 것 같습니다.

2. 추가

이 스크립트 기능을 저에게 맞게 양념을 추가하여 사용하고 있습니다. 물론 이 기능들은 그리 필요하지 않은 기능이지만 저에게는 필요한 것이라 쓰고 있는 것뿐입니다.


2.1 필요한 기능 2019.05.30 추가

  1. <small>를 많이 사용하는데 이부분을 있으면 앞부분까지 출력 해야합니다.
  2. <em>, <code>를 사용하지만 태그만 삭제 합니다.
  3. & 혹시 모를 '&'기호들이 있으면 앞부분까지 출력 해야합니다.
  4. <i>태그는 시작부터 끝나는 태그까지 모두 지워야 합니다. (2019.05.30 추가)

4번란은 icon을 사용시 아이콘 부분을 지워서 출력합니다.


이제 소스 부분입니다. dynamicscrollspy.js 파일을 먼저 수정 하겠습니다.


2.2 function makeTree() 부분입니다.

//setup the tree, (first level)
function makeTree() {
  var tree = self.tree;
  $('H' + self.options.tH).not(self.options.exclude).each(function() {
    //run the first level
    tree[$(this).prop('id')] = {
      dstext: encodeHTML($(this).text()),
      jqel: $(this)
    };
  });

  if (self.options.tH + 1 <= self.options.bH) {
    //only recurse if more than one level requested
    itCreateTree(tree);
  }

  return tree;
}
//setup the tree, (first level)
function makeTree() {
  var tree = self.tree;
  $('H' + self.options.tH).not(self.options.exclude).each(function() {

    // 추가 {
    var n = $(this).html(),
    htopword;

    if (n.includes("<i")) { // 2019.05.30 추가
      var nt = n.substr(n.indexOf("<i"), (n.indexOf("</i>") + 4)-n.indexOf("<i")); // <i class="icon-home"></i> 를 알아내기
      n = n.replace(nt, ""); // <i class="icon-home"></i> 를 지우기
    };

    var s = n
      .trim()
      .replace("<em>", "")
      .replace("</em>", "")
      .replace("<code>", "")
      .replace("<code>", "");

    if (s.includes("&")) htopword = s.substr(0, s.indexOf("&"));
    else if (s.includes("<")) htopword = s.substr(0, s.indexOf("<"));
    else htopword = s;
    // } 추가 

    //run the first level
    tree[$(this).prop('id')] = {
      dstext: encodeHTML(htopword), // dstext: encodeHTML($(this).text()), -> dstext: encodeHTML(htopword), 로 변경
      jqel: $(this)
    };
  });

  if (self.options.tH + 1 <= self.options.bH) {
    //only recurse if more than one level requested
    itCreateTree(tree);

  }

  return tree;
}

function makeTree() 이 부분은 첫번째 'H' 태그에 관한 것입니다.


2.3 function itCreateTree(what) 부분입니다.

//iterate through each grandchild+ level of the tree
function itCreateTree(what) {
  for (var k in what) {
    //skip empty items
    if (k === '') continue;
    // skip if text or element
    if (k == 'dstext' || k == 'jqel') continue;
    //get the current level
    var lvl = Number($('#' + k).prop('tagName').replace('H', ''));
    //end if we are at the final level
    if (lvl >= self.options.bH) return false;
    //next until
    $('#' + k).nextUntil('H' + lvl).filter('H' + (lvl + 1)).not(self.options.exclude).each(function() {
      what[k][$(this).prop('id')] = {
        dstext: encodeHTML($(this).text()),
        jqel: $(this)
      };
    });
    //keep recursing if necessary
    if (lvl < self.options.bH) itCreateTree(what[k]);

  }
}
//iterate through each grandchild+ level of the tree
function itCreateTree(what) {
    for (var k in what) {
    //skip empty items
    if (k === '') continue;
    // skip if text or element
    if (k == 'dstext' || k == 'jqel') continue;
    //get the current level
    var lvl = Number($('#' + k).prop('tagName').replace('H', ''));
    //end if we are at the final level
    if (lvl >= self.options.bH) return false;
    //next until
    $('#' + k).nextUntil('H' + lvl).filter('H' + (lvl + 1)).not(self.options.exclude).each(function() {

      // 추가 {
      var i = $(this).html(),hzword;

      if (i.includes("<i")) { // 2019.05.30 추가
      var itstr = i.substr(i.indexOf("<i"), (i.indexOf("</i>") + 4)-i.indexOf("<i")); // <i class="icon-home"></i> 를 알아내기
      i = i.replace(itstr, ""); // <i class="icon-home"></i> 를 지우기
      };
 
      var o = i
        .trim()
        .replace("<em>", "")
        .replace("</em>", "")
        .replace("<code>", "")
        .replace("</code>", "");
if (o.includes("&")) hzword = o.substr(0, o.indexOf("&")); else if (o.includes("<")) hzword = o.substr(0, o.indexOf("<")); else hzword = o; // } 추가
what[k][$(this).prop('id')] = { dstext: encodeHTML(hzword), // dstext: encodeHTML($(this).text()), -> dstext: encodeHTML(hzword), 로 변경 jqel: $(this) }; }); //keep recursing if necessary if (lvl < self.options.bH) itCreateTree(what[k]); } }

function itCreateTree(what) 부분은 선두 'H' 보다 하위 부분입니다.


2.4 CSS부분

보충으로 CSS 부분도 추가하였습니다. 설명 좀 하자면 가로최대치가 230px이라 글자가 넘어가면 보기가 좋지 않아 조정하고 그 이상이면 '...'을 표시하랍니다. 사실 처음에는 스크립트로 하려고 했지만 CSS 부분이 좀 더 깔끔한 것 같아 CSS를 사용하였습니다.

.nav-link {
  max-width: 230px;
  display: block;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}


2.5 HTML 부분

끝으로 적용을 하는 부분입니다. 사실 이 부분은 데모 부분만 봐도 알 수 있습니다. 하지만 약간의 설명할 부분이 있어 이렇게 적었습니다. 소스를 보시면 알 수 있듯이 tH,bH가 있습니다. 이 부분을 조정하였습니다. 230px라는 가로 사이즈에 너무 많이 있으면 비효율적일 것 같아 H2,H3만 적용되도록 하였습니다.

skin.html </head>위에 비치

<link rel="stylesheet" href="./images/dynamicscrollspy.min.css">

스킨에 맞게 수정하여 사용합니다.

skin.html 스킨에 맞게 비치

<!-- 목차 출력 부분(스크립트) { -->
<div id="scrollspy"></div>
<!-- } 목차 출력 부분(스크립트) -->


skin.html </body>이나 </s_t3>위에 비치

<script src="./images/dynamicscrollspy.js"></script>
<script src="./images/scrollspy.min.js"></script>

<script>
// 목차 출력
$(function() {
  $('#scrollspy').DynamicScrollspy({
    tH: 2, // 시작 h태그
    bH: 3, // 끝 h태그
    genIDs: true
  });
});
</script>


3. 마치며

참고로 티스토리에서 적용하려면 스킨을 약간 조정을 하셔야 합니다. 이 자바스크립트는 body 부분을 적용하는 것이라 스킨에 해당 부분이 있으면 출력되어 버립니다. 물론 조정도 가능하니 html 부분에 적었습니다. 이상 허접한 스킨의 TOC설명이였습니다. 설명도 잘하지 못하지만 말 제주 또한 없어서 읽으시는 데 어려움이 없었나 모르겠습니다. 너그럽게 봐주시길 바랍니다.



728x90