はじめに
こんばんは、こうへいです。デザインの参考に他のサイトを物色してたところ、自分が見ている場所に合わせて目次を自動でハイライトしてくれる機能を見つけたので、自分のサイトでも実装してみたいと思います。閲覧位置に追従するサイドバー目次を作成した後に、自動ハイライト機能を追加するイメージです。
追従するサイドバー目次の作成
はじめに追従機能を持った目次をサイドバーへ追加します。WordPress画面から外観→ウィジェット→[C] 目次→サイドバースクロール追従を選択してウィジェットを追加し、以下を設定します。
- タイトル : 目次
- 目次表示の深さ : H4見出しまで
既にサイドバースクロール追従エリアには、「アーカイブ」と「カテゴリ」が存在していますが、こちらは邪魔なので消してしまいます。また、サイドバーエリアの「最近の投稿」、「最近のコメント」も消します。
こちらは以下のサイトを参考にしました。
自動ハイライト機能の追加
ここから自動ハイライト機能を追加しますが、プログラム(CSS、JavaScript)のカスタマイズが必要となります。カスタマイズに失敗した場合に元に戻せないと困りますので、現状の環境をバックアップして復元可能な状態にしておきます。
WordPress設定のバックアップ
ここでは、BackWPupというプラグインを利用します。WordPress画面からプラグイン→新規追加まで移動し、BackWPupで検索してインストール&有効化します。以下のサイトを参考にしました。
自動バックアップ
今後、何か不測の事態が起きた時のために定期的に自動バックアップしてくれる機能を設定します。WordPress画面からBackWPup→新規ジョブを追加まで移動し、以下を設定します。
- 一般→ジョブ名→このジョブの名前 : 自動バックアップ
- 一般→ジョブの宛先→バックアップファイルの保存方法 : フォルダーへバックアップ
- 一般→バックアップファイルの作成→アーカイブ形式 : Tar GZip
- スケジュール→ジョブスケジュール→ジョブの開始方法 : WordPressのcron
- スケジュール→実行時間をスケジュール→スケジューラー : 毎月1日03:00
- DBバックアップ→バックアップファイルの圧縮 : GZip
手動バックアップ
今回のように、カスタマイズする場合には手動でバックアップする方法が良いため、こちらも設定しておきます。WordPress画面からBackWPup→新規ジョブを追加まで移動し、以下を設定します。
- 一般→ジョブ名→このジョブの名前 : 手動バックアップ
- 一般→ジョブの宛先→バックアップファイルの保存方法 : フォルダーへバックアップ
- 一般→バックアップファイルの作成→アーカイブ形式 : Tar GZip
- スケジュール→ジョブスケジュール→ジョブの開始方法 : 手動
- DBバックアップ→バックアップファイルの圧縮 : GZip
ジョブを作成したら、WordPress画面からBackWPup→ジョブまで移動し、手動バックアップを今すぐ実行。バックアップが完了したら、契約しているサーバーのファイル情報を見に行き、バックアップファイルを探してローカルにダウンロードしておきます。
エックスサーバーでは、ドメイン名/public_html/wp-content/uploads/backwpup-***-backups/にありました。
コード編集
以上でカスタマイズの準備が整いましたので、WordPress画面から外観→テーマファイルエディターまで移動し、以下のコードを書き込みます。
/*サイドバースクロール目次(id="toc-4")のliタグ(class="current")へ*/
#toc-4 li.current {
background-color: #ff9244; /* ハイライト色 */
}
$(function() { //予約関数(HTMLが全て読み込まれてから実行)
// サイドバースクロール目次(id="toc-4")の
// 見出しアンカーリンクタグ(liタグ内のaタグ)を全て取得
const headerLinks = $('#toc-4 li a');
// コンテンツの位置(top, botttom)情報の配列作成
let contentsPos = new Array();
// contentsPos の初期化関数
function init() {
for (let i = 0; i < headerLinks.length; i++) {
// 見出し i のリンク先idを取得
const headerID = headerLinks.eq(i).attr('href');
// コンテンツ i の先頭位置
const top = $(headerID).offset().top;
// コンテンツ i の終了位置(暫定的に null )
const bottom = null;
// 配列として格納
contentsPos[i] = { top: top, bottom: bottom };
// コンテンツの下部の位置を調整
if (i > 0) {
// 前のコンテンツの終了位置 = 今のコンテンツの先頭位置
contentsPos[i - 1].bottom = top;
}
};
// footerの先頭位置を取得
const footerTop = $("footer").offset().top;
// 最後のコンテンツの終了位置 = footerの先頭位置
contentsPos[contentsPos.length - 1].bottom = footerTop;
}
// 現在位置を確認してコンテンツ位置に対応
function currentCheck() {
// 現在のサイト上部からの位置を取得
const windowScrollTop = $(window).scrollTop();
const windowsCenter = window.innerHeight / 2;
// 一旦全マークを解除
headerLinks.parent().removeClass('current');
// 現在位置が全コンテンツ内にあるかチェック
if (contentsPos[0].top <= windowScrollTop + windowsCenter && contentsPos[contentsPos.length - 1].bottom > windowScrollTop + windowsCenter) {
for (let i = 0; i < contentsPos.length; i++) {
// 現在位置がコンテンツ i 内にあるかチェック
if (contentsPos[i].top <= windowScrollTop + windowsCenter && contentsPos[i].bottom > windowScrollTop + windowsCenter) {
// class = "current"を aタグの親である li タグに設定
headerLinks.eq(i).parent().addClass('current');
break;
}
}
}
}
//ここからメイン
// 初期化の実行
init();
// ロード・スクロール時に見出しをマーク更新
$(window).on('load scroll', currentCheck);
// アコーディオンが開閉したら座標更新
$(document).on('change', 'input.toggle-checkbox', function() {
setTimeout(init, 350);
});
// 目次が開閉したら座標更新
$(document).on('change', 'input.toc-checkbox', function() {
setTimeout(init, 550);
});
});
今回は、コンテンツ位置(contentsPos[i].top)が現在の閲覧画面の中央ライン($(window).scrollTop() + window.innerHeight / 2)より上にある場合にハイライト表示するようにしています。
toc-4という文字列が出てきますが、これはサイドバースクロール目次を示すIDであり、環境によって異なる場合があります。これを確認するためには、自分のサイトでF12キーを押して、HTMLを表示させます。Control+Fキーで検索バーを開き、tocで検索してみてサイドバースクロールの目次に該当するものを探しましょう。
こちらを参考にしました。
コメント