Ghost Blogにヘッドラインを追加する

前項Ghost Blogにテーブル表示を追加すると似た話で、今度は各ポストにヘッドラインを付けてみる。これはそのポスト中の<h2〜6>タグの内容を拾ってリストにするものだ。


    jquery.ex-make-index.js

    このスクリプトはjQuery Extensionになっており、ロードが完了するとjQuery.makeIndex()メソッドが使用可能になる。なお上位Extensionとしてjquery-ui.jsを必要(依存)1する。

    //
    // jquery.ex-make-index.js
    //
    // $Id: make-index.js 143 2015-05-08 09:31:06Z askn $
    //
    (function ($) {
        $.fn.makeIndex = function (config) {
            var serial = 0;
            var defaults = {
                search: 'section.post-content',
                footnotes: 'div.footnotes',
                foottitle: 'Foot Notes',
            }
            var options = $.extend(defaults, config);
            this.each(function (i) {
                var $this = $(this);
                $(options.search).find("h2, h3, h4, h5, h6").each(function (i) {
                    var current = serial++;
                    var id = "mi_" + current;
                    var $self = $(this);
                    var title = $self.text();
                    $("<a/>")
                        .attr({name:id})
                        .insertBefore($self);
                    $("<li/>")
                        .append($("<a/>")
                            .attr({href:"#"+id})
                            .click(function () {
                                var href = $(this).attr("href").replace(/#/,"");
                                var bottom = $("a[name=" + href + "]").offset().top;
                                $('html,body').animate({scrollTop:bottom}, 1000, "easeOutExpo");
                                return false;
                            }).text(title)
                    ).appendTo($this);
                });
            });
            return this.each(function (i) {
                var $this = $(this);
                var current = serial++;
                var id = "mi_" + current;
                $("<a/>")
                    .attr({name:id})
                    .insertBefore($(options.footnotes));
                $("<li/>")
                    .append(
                        $("<a/>")
                            .attr({href:"#"+id})
                            .click(function () {
                                var href = $(this).attr("href").replace(/#/,"");
                                var bottom = $("a[name=" + href + "]").offset().top;
                                $('html,body').animate({scrollTop:bottom}, 1000, "easeOutExpo");
                                return false;
                            }).text(options.foottitle)
                    ).appendTo($this);
            });
        };
    })(jQuery);
    
    // End of Script
    

    これをindex.jsから次のようにして呼び出す。searchオプションで検索対象のセレクタを指定し、その中で見つかる<h2〜6>のアンカーを作成する。<h1>はポストヘッダなので収集しない。またfootnotesオプションで追加のアンカーをひとつ与えることが出来る。またアンカーはアニメーションスクロールによる画面切り替えでひと呼吸いれ、目で置いやすいようにした。

        $("ul.index").makeIndex({
            search: 'section.post-content',
            footnotes: 'div.footnotes',
            foottitle: '注釈',
        });
    

    こうして作成したアンカーリストは、ポスト中の次の記述の箇所に流し込まれる。

      <ul class="index"></ul>
    

    縦方向のスクロール量が数画面分だったりセクション数が数えるほどならこういう機能は必要ないだろうし、長くなるようならポストを分割したほうが良い場合が多い。だが記事構成上どうしてもひとつのポストに押し込みたい場合はこういうExtensionがあったほうがユーザビリティを補えるだろう。


    1. 依存すると言っても animateメソッドのオプションだけなので、ここを修正すればjQuery UIがなくても問題はない。

    RECENT LINKS