今回のはてなブログカスタマイズは、記事の目次をサイドバーにも表示するものです。
記事のよこに目次を置き、スクロール追従させることで、読んでいるところを把握することができ、記事が読みやすくなります。
記事が長い場合に効果的です。
当カスタマイズは、スクロール追従させることを想定したカスタマイズ内容になっています。
事前準備
目次をサイドバーに表示するために、表示用のHTMLモジュールを追加します。
HTMLモジュールの追加方法がわからない場合は、コチラの記事を参考にしてください。
スクロール追従させる場合
記事の目次
目次の表示方法
記事の目次を表示するには、記事編集画面で入力補助ツールバーから「目次」ボタンをクリックします。
という文字が入力され、この文字の位置に記事の目次が表示されます。
記事の見出しが目次として表示されます。
サイドバーに表示する
ここからは、本題のサイドバーに目次を表示する手順になります。
※当カスタマイズでは、jQueryを使用しています。jQueryの設置方法は「jQueryの設定方法 - jQueryを使用するまでの手順 |【jQuery】 - IT the Best」をご覧ください。
本題のサイドバーに表示する方法ですが、当記事ではHTML要素のクローンを生成して表示します。
- 目次のクローン生成からサイドバーへの表示
サイドバーの一番下に空のHTMLはてなモジュールを作成し、そこに目次を追加します。
<script>
var toc=$(".entry-content .table-of-contents"); // 目次
if (toc.length>0) { // 目次が存在する
var toc_clone=toc.clone(true); // 目次のクローン生成
var sidebar_last=$("#box2-inner>.hatena-module.hatena-module-html").last() // サイドバーの一番下のモジュール
var tocHatenaModule=$(document.createElement("div")).addClass("hatena-module hatena-module-html").append($(document.createElement("div")).addClass("hatena-module-body").append(toc_clone))
sidebar_last.after(tocHatenaModule); // サイドバーのいっちばんしたのモジュールに追加
}
</script> - サイドバーに表示した目次の固定
<style>
#box2-inner{
height:100%;
}
#box2-inner>.hatena-module:last-child{
position: sticky; /* スクロール追従 */
top: 10px;
}
</style>
これで、記事の目次をサイドバーに表示することができます。
※JavaScriptはサイドバーより後に記述します
強調表示
記事を読んでいるときに、どの目次内を読んでいるのかわかるように目次を強調表示する処理を追加しました。
これは、スクロールするたびに見出しの位置を取得し、その見出しが画面トップに来た時に目次を強調表示させるものです。
今回は、記事の見出しがページトップに来た時に、目次にクラスの追加/削除を行い強調表示をします。
<script>
$(window).on("scroll", function (e) { // スクロールするたびに呼ばれる
var targetElement=false; // 強調表示を行う要素
$("#box2-inner .hatena-module .table-of-contents li>a").each(function (i, element) {// 目次の見出しごとの処理
var headingName = $(element).attr("href").replace(/^#/, ""); // 見出し名
var headingPosition = $("#" + headingName)[0].offsetTop; // 見出しの位置格納
$(element).removeClass("toc-highlight"); // 強調表示クラスの削除
if (window.scrollY>=headingPosition) { // 見出し位置がスクロール量より小さい
targetElement=element; // 強調表示を行う要素を更新
}
});
if (targetElement) {
$(targetElement).addClass("toc-highlight"); // 強調表示クラスの追加
}
});
</script>
<style>
.toc-highlight{
background:blue;
color:white;
}
</style>