調べたこと、作ったことをメモしています。
こちらに移行中: https://blog.shimazu.me/

TumblrでjQueryつかって目次を自動生成する

はじめに

上のページを参考にしてやってみたところ、このスクリプトでは複数記事があった場合に対応できないのと、h1, h2タグの階層構造に対応していないことに気づいて、ちょっと不便だな、となった。ということで、改良したからメモ。

目次

やりかた

Step1: JQueryを使えるようにする

<script src="//code.jquery.com/jquery-1.11.3.min.js"></script>

上記コードをテーマのHTMLのヘッダかどっかに突っ込む。

Step2: JSのコードの追加

追加するコードは以下。これをテーマのヘッダかどこかに入れる。

function getLevel(tagName) {
    if (tagName.toLowerCase() == "h1")
      return 1;
    else if (tagName.toLowerCase() == "h2")
      return 2;
    else
      return -1;
}

$(function() {
  $(".toc").each(function() {
      var toc = $(this);
      var article = $(this).closest("article");
      var article_id = article.attr("id");
      var toc_id = "toc-" + article_id;
      var index_tree = $('<ul></ul>');
      var current_node = index_tree;
      var prevLevel = 1;
      article.find("h1,h2:not(.post-title)").each(function(i) {
          var id = '' + article_id + '-chapter-' + i;
          $(this).attr('id', id);
          var level = getLevel($(this).get(0).tagName);
          var text = '<li><a href="#' + id + '">' + $(this).html() + '</a></li>';
          if (level > prevLevel) {
              var new_node = $('<ul></ul>');
              current_node.find("li:last").append(new_node);
              current_node = new_node;
              prevLevel = level;
          } else if (level < prevLevel) {
              current_node = current_node.parent().closest("ul");
              prevLevel = level;
          }
          current_node.append(text);
          $(this).append('<span class="back-toc"><a href="#' + toc_id + '">↑</a></span>');
      });
      $(this).append(index_tree);
      $(this).attr('id', toc_id);
  });
});

$(function() {
    $('a[href^=#]').click(function() {
        var speed = 400;
        var href = $(this).attr("href");
        var target = $(href == "#" || href == "" ? 'html' : href);
        var position = target.offset().top;
        $('body,html').animate({
            scrollTop: position
        }, speed, 'swing');
        return false;
    });
});

Step3: 本文に目次をつける

本文中の目次つけたいところにこれを置く。

<div class="toc"></div>