サイドバーに現在位置を表示して追尾する目次を設置する【Ver3】

いわゆるシングルページナビゲーションみたいなやつ。

できること

  • サイドバーに目次を設置
  • スクロールすると追尾する
  • 現在位置の背景色変更
  • リンク先へのスムーズスクロール
  • ウィンドウサイズ変更に合わせてサイズ変更
  • 記事ページ以外でもページ内の記事一覧などを表示

動作環境

  • サイドバーが横に表示されるテーマ
  • 親要素にtransformがないテーマ

動作確認はPC版のChromeFireFox、Edge、IE11で行っています。
※設定によってはスマホタブレットでも動きますが基本的にPC向けです。

前バージョンからの主な変更点

  • ウィンドウサイズ変更に対応
  • 使えるテーマが増えた

他にもCSSのIDとクラス名が変わったり、jQuery使うのをやめたりと変更点が多いです。

その他の変更点

インストール

念のため追加する前の設定は保存しておきましょう。

HTML

デザイン設定の[カスタマイズ]-[サイドバー]-[モジュールを追加]-[HTML]に貼り付ける。
タイトルはスクリプトが読み込まれた段階でスクリプト側で指定したものに置き換えられます。

JavaScript

デザイン設定の[カスタマイズ]-[フッタ]に追加する。

CSS

デザイン設定の[カスタマイズ]-[デザインCSS]に追加する。

設定について

フッタに追加したスクリプトの冒頭部分を変更することである程度動作を変えられます。
テーマによっては設定を変えないと動きません!(変えても動かないテーマもありますが…)

ここで説明するもの以外についてはこちら→ その他の設定値

メディアクエリ(重要)

変数名 デフォルト
MATCH_MEDIA false
MEDIA_QUERY_SIDEBAR '(min-width: 768px)'

デフォルトではサイドバー要素が横に表示されているかを#box2要素にfloatプロパティがあるかで判定しています。
しかしテーマによってはこの方法では判別できないので、かわりにメディアクエリを使います。

MATCH_MEDIAtrueMEDIA_QUERY_SIDEBARをテーマに合った値にします。この値はF12を押すと出るデベロッパーツールなどで調べましょう(説明がつらい)。
ちなみにデフォルトで入ってる'(min-width: 768px)'だと「ページの横幅が768px以上」ならサイドバーが表示されているという意味になります。

目次を表示するページ

記事ページでは普通に見出し一覧を表示しますが、トップページやアーカイブページでは記事タイトル一覧を目次として表示できます。

デフォルトでトップページやアーカイブページでも表示するように設定されていますが必要に応じて変更してください。
詳しくはこちら→ PAGES options

表示する見出しタグ

変数名 デフォルト
HEADLINE_QUERY ['h3', 'h4', 'h5']

目次に表示したい見出しタグを指定します。数字が小さい順に書いてください。

固定時の余白

変数名 デフォルト
MARGIN_TOP 10
MARGIN_BOTTOM 0

目次モジュールが固定(追尾)される時の上下の余白を指定できます。

グローバルメニュー

変数名 デフォルト
GLOBAL_HEADER ['#globalheader-container']
  • 追尾開始位置を正しく取得するために、ヘッダーメニュー・グローバルメニュー等と呼ばれる常時表示・追尾型のメニュー(上に表示されるもの)のidclassを指定します
  • idの場合は#classの場合は.を先頭に書いてください
  • 複数指定する場合は['#globalheader-container', '.global-menu']のようにコンマで区切って書きます
  • Pro版でヘッダを非表示にしている場合はデフォルトの'globalheader-container'は消しても大丈夫ですが[]は残してください
  • 目次と重なる時はMARGIN_TOPを調整します

スムーズスクロール

変数名 デフォルト
SCROLL_TIME 400
SCROLL_TIME_TOUCH 400
  • スムーズスクロールにかける時間をミリ秒で指定できます(TOUCHが付いてる方はタッチデバイスでのスクロール時間)
  • 0にするとスムーズスクロールはオフになります

HTML構造

色が薄い所ははてなブログ側で用意される部分です。
nav#stocはインストール時に貼り付けたHTML)

f:id:Twilyze:20180110044204p:plain

追尾中#stoc-moduleに付与されるクラスの条件

  • tracking ウィンドウかページに固定している時
    • fixed ウィンドウに固定している時
    • absolute ページに固定(下までスクロール)している時
  • fade-in 他のサイドバーモジュールより上に設置していて追尾開始した時

仕様と注意点

  • 見出しが設定値より少ない・表示する設定にしていないページの時はモジュール全体を非表示にします
  • 目次記法による目次が表示されていない時のページ内リンクはsection0, section1...になります
  • 目次やメニューの開閉などでページの高さが後から変わったりするとスクロールの移動先や現在位置表示はずれます
  • 沢山サイドバーモジュールを設置していると見づらいので置き過ぎには注意しましょう

タッチデバイスでの動作

レスポンシブデザインモードやPro機能、「PC版サイト表示」などをしない限りあまり関係ない話。

スマホなどタッチデバイスでのスクロール処理はPCと違うので追尾が不自然になったりします。これを解決するためにタッチデバイスの時はposition:stickyIE11未対応)を使っているのですが、そのために以下の処理が入ります↓

  • #stoc-module#stoc.touchクラスを追加
  • ブラウザがposition:stickyに対応していれば#stoc-module.stickyクラスを追加
    • サイドバーモジュールの親要素#box2-innerの高さを記事部分#main-innerの高さと合わせる

#box2-innerの高さを変更した影響でテーマによっては見た目が変になりますが仕様です。

こんなときは

デザイン・色が合わない

テーマによっては追尾中に背景色がなくなるなどの症状が出ます。

簡易的ですが以下の公式テーマ向けの例→ カスタマイズ例

  1. Aero
  2. Afternoon
  3. ヨミカキ by kanahei
  4. Popcorn by カタノトモコ
  5. Report
  6. レトロポップ
  7. Skull wings
  8. Solid
  9. Terminal
  10. Venetia

目次の上下に白いグラデーションが表示される

ページの縦幅よりも目次が大きい時にスクロールバーとさらにスクロール可能かを分かりやすくするための表示があるんですが、
f:id:Twilyze:20180115011054p:plain
デフォルトでは白い背景色に合うように設定されているのでテーマに合わせて変更する必要があります。

[デザインCSS]に追加した以下の部分を

  • /* Shadows */の下に2つあるrgba(0,0,0,.16)(透明度のある黒)を表示したい色
  • /* Shadow covers */の下に2つある#fff(真っ白)を背景色と同じ色

にそれぞれ設定します

/* sidebar_toc.css */
#stoc {
  /* Shadows */
  background:
    radial-gradient(farthest-side at top, rgba(0,0,0,.17), transparent) top / 100% 11px,
    radial-gradient(farthest-side at bottom, rgba(0,0,0,.17), transparent) bottom / 100% 11px;
}
#stoc > ol {
  /* Shadow covers */
  background:
    linear-gradient(#fff 30%, transparent) top / 100% 40px,
    linear-gradient(transparent, #fff 70%) bottom / 100% 40px;
}

この表示自体いらない場合はbackground-repeatbackground-attachmentも一緒に消してください。

フッタに空の要素が表示される

フッタにスクリプトを書いた影響でテーマによっては空の#bottom-editarea要素が表示されます。非表示にしたい場合は[デザインCSS]に以下を追加してください。

#bottom-editarea {
  display: none;
}

フッタに他の要素がある場合動作がおかしくなるかも知れないので注意。

追尾する位置になると画面外に消える

親要素にアニメーション等でtransformが使われているとposition:fixedが上手く動かなくなり表示できません。

position:fixedが効かない事件簿 - Qiita

position:stickyを使うモードにすると治る可能性があります(F_STICKY_MODE)。たぶん。
親要素にoverflow:hiddenがあると動かないので注意。

なにかいい方法があるかも知れませんが基本的に親要素にtransformは使用しないでください。

あとがき

まさかの大型バージョンアップ3回目。もうここまで大きな更新はしない(はず)。

なるべく分かりやすいように作りたかったけど分かりづらいですね申し訳ない。各自頑張って。
正直標準の公式テーマ対応するだけで力尽きたので他のテーマだと動かないかも。。


要望やバグ報告はコメント欄かGoogleフォームの方へどうぞ。
ただし対応する可能性は低めなのであまり期待しないでお願いします。

参考