クリアメモリ

プログラミングやガジェットレビュー、便利なアプリケーションなど雑多に記録するブログ

【はてなブログ】目次を開閉式にカスタマイズしてみた

f:id:clrmemory:20171121155812p:plain

こんにちはクリアメモリです!

先日、はてなブログの記事中に目次を設置する方法を紹介しました。

もし、目次に表示する見出しの数が10以上あったりして、目次だけでページが埋まってしまうような場合、開閉式にすることでスペースを削減できます。

 

そこではてなブログの目次を開閉式にカスタマイズしてみたので紹介します。

 

はじめに

 

今回紹介する方法では、【はてなブログで記事中に目次を自動で設置する方法】で紹介したコードをベースに作成していきます。

目次を設置するコードについては、今回はあまり深く触れないので先に確認しておくと良いかもしれません。

 

www.clrmemory.com

 

この記事の中では以下のような目次が完成しました。

 

f:id:clrmemory:20170528093357p:plain

 

目次は設置できたのですが、スマホから記事を確認した場合、見出しの数が10以上あると画面全体に目次が表示されたり、スクロールの邪魔になってしまっていました。

そこで、以下の画像のような【目次の開閉ボタン】を設置することで、目次の量が多くても少なくても同じスペースにすることができます。

 

f:id:clrmemory:20170528093733p:plain

 

実際の動作を確認しよう

 

目次の右上に【 ^ 】のようなボタンがあると思います。

このボタンをクリックすると目次のリスト部分が閉じ、スペースを省略できます。

 

f:id:clrmemory:20170528094014p:plain

 

また、目次を開く時と閉じる時は、アニメーションで動作するようにしました。

 

 

これなら見出しの数が多くても問題なく目次を表示できますね。

私の場合、スマホ版のみ目次を開閉式にしているので、スマホ表示でアクセスすると確認できるかと思います。

 

では、実際に目次に開閉ボタンを設置していきましょう。まずはcssから編集します。

 

スタイルを調整

 

では、今回設置するコードを確認してください。

 

.section-list {
    overflow: hidden;
    min-height: 38px;
    border: 1px solid #adadad;
    background-color: #eaf4ff;
}
p.toc {
    position: relative;
    text-align: center;
    margin-top: 5px;
    margin-bottom: 0;
    padding-bottom: 5px;
    border-bottom: 1px dotted #adadad;
    color: #5e9cff;
}
.section-list > ol {
    list-style: none;
    display: none;
    margin-left: 15px;
    margin-top: 10px;
    border: 0;
    padding: 0;
}
.section-list > ol > li > a {
    color: #5e9cff;
    font-weight: 500;
}
.h3-section{
    padding-left: 15px;
}
.section-list p i {
    position: absolute;
    top: -2px;
    right: 20px;
    cursor: pointer;
    transition-duration: .2s;
}

 

今回はこのようなcssを用意しました。

これをコピーして、デザインCSSの中に追加します。もし、スマホ版のみ設定したい場合は、以下の記事を参考にして追加してください。

 

www.clrmemory.com

 

さて、このcssの中で重要な箇所を確認しておきましょう。

 

transition-duration: .2s;

 

このコードでは、開閉ボタンのアニメーションが完了するまでの時間を表しています。

例えば、この値を10sなどにしてみると、アニメーションが完了するまでに10秒かかるということになります。自由に変更してみてください。

 

jQueryを作成

 

続いて、jQueryから【クリックされたら開閉する】処理を追加していきます。

すでに目次が設置されている方は、その部分を削除か隔離してから追加してください。

 

jQueryを追加

サイトカスタマイズで、まだjQueryを追加していない方は、最初に以下のコードを設置しておいてください。

<script type="text/javascript" src="http://code.jquery.com/jquery-1.9.1.min.js"></script>

 

このコードがすでに設置されているのであれば、この作業は不要です。

 

目次を表示する

 

<script type="text/javascript">
addEventListener("DOMContentLoaded", function() {
    var list = "";
    var $point = $('.entry-content h2');
    var className = "";
    var h2_count = 0;
    var h3_count = 0;
    var text = "(show)"

    // h2見出しを検索
    $(".entry-content h2, h3").each(function(i){
        var idName = "section"+i;
        var count = 0;

        if($(this).is('h2')){
          h2_count++;
          h3_count = 0;
          count = h2_count;
          className = "h2-section";
        }else if($(this).is('h3')){
          h3_count++;
          count = '' + h2_count + '.' + h3_count;
          className = "h3-section";
        }
        $(this).attr("id",idName);
        list += '<li class = ' + className + '><a href="#' + idName + '">' + count + '. ' + $(this).text() + '</a></li>';
    });
    // h2見出しが2つ以上あったら目次を表示する
    if ($(".entry-content h2").length >= 2){
      while($point.eq(0).prev('p').html() === '&nbsp;' || $point.eq(0).prev('p').prop('outerHTML') === '<p></p>'){
        $point.eq(0).prev('p').remove();
      }
      $point.eq(0).before('<p class="more-paragraph" style="overflow:hidden"></p>');
      $("<div class='section-list'><p class='toc'>目次 <i class='show-hide fa fa-2x fa-angle-down'></i></p><ol>" + list + "</ol></div>").appendTo($point.eq(0).prev('p'));
        // $point.eq(0).before($content);
    }
    // 見出しへのスクロールを滑らかにする
    $('.section-list a').on("click", function() {
        $('html,body').animate({scrollTop: $(this.hash).offset().top}, 600);
        return false;
    });
    //見出しを開閉式にする
    $('.show-hide').on("click", function(){
      var $section_ol = $('.section-list > ol');
      
      if($section_ol.is(':visible')){
        $section_ol.slideUp(200);
        $('.show-hide').css("transform","rotate(0deg)");
      }else{
        console.log('section');
        $section_ol.slideDown(200);
        $('.show-hide').css("transform","rotate(180deg)");
      }
    });
}, false);
</script>

 

このようなコードを記事下あたりに設置することで、開閉機能つきの目次が表示されました。

また先日紹介したように、目次の見出し部分をクリックすることで、それに対応した場所まで自動でスクロールするようになっています。

 

これではてなブログに開閉式の目次が設置できました。

 

f:id:clrmemory:20170528101739p:plain

 

サクッと解説

 

今回のコードでは、先日紹介した目次を設置するコードを元に、開閉式にカスタマイズしてあります。

 

具体的に重要な箇所は

 

    //見出しを開閉式にする
    $('.show-hide').on("click", function(){
      var $section_ol = $('.section-list > ol');
      
      if($section_ol.is(':visible')){
        $section_ol.slideUp(200);
        $('.show-hide').css("transform","rotate(0deg)")
      }else{
        console.log('section');
        $section_ol.slideDown(200);
        $('.show-hide').css("transform","rotate(180deg)")
      }
    });

 

このコードでは、クリックされた時に目次の【ol (見出しが表示される場所)】が表示されていたら非表示にし、非表示なら表示するようにしてあります。

この時に、開閉ボタンを回転させて現在の状態に合わせるようにしました。

 

非表示なら上向き、表示されているなら下向きですね。

こちらのボタンもアニメーションで動作するようになっています。

 

slideDown( )とslideUp( )の中に記述されている【200】は、目次の開閉が完了するまでにかかる時間を表しています。

200は、200秒ではなく200ミリ秒ですので、つまりは0.2秒で開閉するというわけですね。ここの値は自由に変更してみてください。

 

まとめ

 

今回紹介したようなコードを使うことで、はてなブログに設置した目次を開閉式にカスタマイズできました。

同じような方法を使えば、目次以外のコンテンツを開閉式にすることもできるので、ぜひ試してみてください。

 

ではまた。

新着記事