みちのえきまにあ

CBR1000RRで道の駅巡りをしているまったりツーリングライダーのブログ

ブログの目次と見出しとの間をヌルっと移動できるようにしてみました

はい。
毎回ブログには適当に見出しを付けているわけですが、前回のエントリあたりからその見出しのための目次を最初に書くようにしました。
で、今回はその目次から見出しへ、見出しから目次へと簡単にヌルっと移動できるようにしてみたというお話です。

そもそもどんな動きなのか

目次と見出しとの間をヌルっと移動 と言ってもよくわからないかもしれないので、実際に動きを見てもらったほうが早いと思います。

この記事の目次の各見出し部分をタップ(クリック)すると、記事中の各見出し部分にヌルっと移動します。
また、記事中の各見出しの右側の上矢印のようなアイコンをタップ(クリック)すると、目次部分にヌルっと移動します。

はてなのブログエディタ内に目次を作成するボタンがありますが、それで作成した場合、目次から各見出しの位置へ移動するときに別ページに飛んだときのような雰囲気になります。(実際は同じページ内で表示位置が変わっているだけですが)

また、一旦目次から各見出し位置へ飛んでしまうと、もう一度目次へ戻ろうとしたときに手でスクロールする必要があります。
個人的にこれは面倒なので、今回の実装にいたったわけです。

javascriptの記述

ではさっそく実装方法に移りたいと思います。
今回も、前回のカテゴリセレクトボックス設置のときのように、以下に記述する内容をコピペしてもらうだけで実装できるようになっています。

記述はjavascriptとcssに分かれますが、記述する場所はどちらも ダッシュボード>設定>詳細設定>headに要素を追加 の部分です。

まずはjavascript部分。

<script src="https://cdn.blog.st-hatena.com/js/external/jquery.min.js?version=1.12.3"></script>
<script>
$(document).ready(function(){
    var $cth = $(".entry-content h1");
    var backToCt = "<div class='back-to-ct'><i class='blogicon-chevron-up'></i></div>";
    if ($cth.length > 0) {
      $(".entry-content h1").append(backToCt);
    } else {
      $cth = $(".entry-content h2");
      if ($cth.length > 0) {
        $(".entry-content h2").append(backToCt);
      }
    }

    $(".content-table-list").click(function(){
      var idx = $(".content-table-list").index(this);
      
      var $cth = $(".entry-content h1");
      if ($cth.length == 0) {
        $cth = $(".entry-content h2");
        if ($cth.length == 0) {
          return false;
        }
      }
      
      var rect = $cth[idx].getBoundingClientRect();
      var position = rect.top + window.pageYOffset - 45;
      
      scrollToPosition(position);
    });
    
    $(".back-to-ct").click(function(){
      var $cth = $(".contents-table h3");
      var position = 0;
      if ($cth.length > 0) {
        var rect = $cth[0].getBoundingClientRect();
        position = rect.top + window.pageYOffset - 45;
      }
      
      scrollToPosition(position);
    });
    
    function scrollToPosition(position) {
      $("html,body").animate({
        scrollTop : position
        }, {
        queue : false
      });
    }
});
</script>

1行目のjQueryの読み込みについては既に記述されている場合は不要です。

で、何をしているかというと、

  • 目次の見出し部分をタップ(クリック)した時に、記事中の見出し位置へヌルっとスクロール
  • 記事中の h1またはh2要素のうしろに上矢印アイコンを追加して、このアイコンがタップ(クリック)された時に、目次位置へヌルっとスクロール

ということをしています。(ざっくりと)

cssの記述

続いてcssの記述です。

<style>
.back-to-ct {
  float: right;
}

これは何をしているかというと、記事中の見出しの右側に目次へ戻るアイコンを追加するわけですが、そのアイコンを右寄せにしているわけです。
正直この記述がなくても動くことは動くのですが、まあ右側に寄っていたほうが自然ですよね。

ブログを書く際の注意点

動きの部分は上記のjsとcssで問題ないのですが、その動きをさせるために、ブログの目次部分を書くときに必要な記述が少しあります。
具体的には、以下のようなhtmlで目次を作成する必要があります。

<div class="contents-table">
  <h3>目次</h3>
  <ol>
    <li class="content-table-list"><u>みだしです</u></li>
    <li class="content-table-list"><u>見出しです</u></li>
    <li class="content-table-list"><u>ミダシデス</u></li>
  </ol>
</div>

ここで必ず守っていただきたいのは、

  • 目次部分を contents-table クラスで囲むこと
  • 「目次」 の記述は h3 タグで囲むこと
  • 見出し名を content-table-list クラスで囲むこと
  • 記事中の移動先見出しとして使用できるのは h1 または h2 のどちらか一方のみ

の4点です。

ですので、「目次」 部分を 「目次ですよ」 に変えたり、リスト部分を ol ではなく ul にしてもらっても結構です。


この4点さえ守ってもらえれば、上記のjsとcssをコピペするだけで目次と見出しの間をヌルっと移動できるようになります。