【WordPress】記事の位置に合わせてサイドバーウィジットの目次をスクロール【カスタマイズ】

目次スクロール

記事の表示位置に合わせて、サイドバーに設置した目次の見出しをハイライトするカスタマイズです。(PCのみ)

また、目次が自動でスクロールするので、現在記事のどこを見ているのか分かりやすくなります。

動作確認テーマ

THE SONIC (動作デモ)

注意

Microsoft Edge、Internet Explorer では目次スクロールが動作しないことを確認しました(見出しハイライトはOK)。自動スクロールはChrome、Firefox のみの対応となります。

目次

サイドバーウィジットに目次を追加

まだウィジットに目次を追加していない場合は追加します。

「WordPress管理画面 > 外観 > ウィジット」を開いて

THE SONIC 目次」を ドラッグアンドドロップ して 「(PC)追尾サイドバー」に追加しましょう。

PCで右側に固定表示される目次です。

目次が表示されない場合は、「管理画面 > 外観 > カスタマイズ > 記事設定 > 目次の設定」を確認してみましょう。

functions.php に追記

functions.php の扱いを間違えるとブログが表示できなくなりますので、かならずバックアップをとってから行ってください。

THE SONIC 子テーマ内の functions.php に下記コードを追記します。

/*************************************************
// 目次ハイライト
**************************************************/
function mkj_highlighter() {
echo <<< EOM
<script>
const mkjHighlight = (e) => {
    const hashes = document.querySelectorAll('.mkj-side-style a');
    const sy = window.pageYOffset;
    const ey = sy + document.documentElement.clientHeight;
    let userAgent = window.navigator.userAgent.toLowerCase();
    let focusEl = [null,null];
    hashes.forEach( (el) => {
        const targetEl = document.querySelector(el.hash);
        const y = sy + targetEl.getBoundingClientRect().top ;
        el.closest('.mkj-list li').classList.remove('mkj-marker');
        el.classList.remove("mkj-active") ;
        if(sy < y &&  y < ey && !focusEl[1]){focusEl[1] = el;focusEl[0] = null;}
        if(sy > y) focusEl[0] = el;
    });
    if (focusEl.length) focusEl.forEach((el) => {
        el && el.classList.add("mkj-active");
        el && el.closest('.mkj-list > li').classList.add('mkj-marker');
        if (userAgent.indexOf('msie') == 1 || userAgent.indexOf('edge') == -1) {
            el && el.scrollIntoView({
                block: 'nearest'
            });
        }
    });
};
mkjHighlight();
window.addEventListener("scroll", mkjHighlight);
</script>
EOM;
}
add_action( 'wp_print_footer_scripts', 'mkj_highlighter' );

style.css に追記

シンプルな目次ハイライト

子テーマ内の style.css に下記コードを追加してください。

目次の見出しの前に丸マークをつけて、色を変更するだけのシンプルなスタイルです。

/*--------------------------------------
サイドバー目次ハイライト
--------------------------------------*/
.mkj-side-style .mkj-content-in {
	max-height: 400px; /*目次の高さ*/
    overflow-y: scroll;
    scroll-padding: 20% 0; /*ハイライトする見出しの位置*/
}
.mkj-side-style .mkj-list li > .mkj-active { /*見出し色*/
	color: #00b1c3;
}
.mkj-side-style .mkj-list.mkj-list-nonum > li:before { /*ドットの場合*/
    box-sizing: border-box;
    top: 13px;
    background: #fff;
    border: 2px solid#00b1c3;
}
.mkj-side-style .mkj-list > .mkj-marker::before,
.mkj-side-style .mkj-list.mkj-list-nonum > .mkj-marker::before  { /*見出し丸*/
	color: #fff;
    background: #00b1c3;
}
.mkj-side-style .mkj-list > li:before{
    top: 4px;
    background: #fff;
    border: 2px solid #00b1c3;
    color: #00b1c3;
    /* border-radius: 50%; */
}
/*目次縦線*/
.mkj-side-style .mkj-list > li:not(:last-child):after {
	content:"";
	width: 3px;
    background: rgba(2,177,195, .1);
    border-color: #fff;
	display: block;
	position: absolute;
	top: 31px;
	bottom: -9px;
	left: -17.5px;
}
.mkj-side-style .mkj-list-nonum > li:not(:last-child):after {/*ドットの場合*/
	top: 26px;
	bottom: -10px;
	left: -13.5px;
}
.mkj-side-style .mkj-list > li.mkj-marker::after { /*縦線*/
	background: #00b1c3;
}
@media (max-width:1029px) {
	.widget_tsnc_table_of_contents {
		display: none;
	}
}

まずはサイドバーの高さを変更してみましょう。max-height: 400px の数字部分を小さくすると、目次の縦幅が短くなります。

この値を 50vh とすると画面の高さの半分のサイズになります。

そして、scroll-padding の値を変更すると、ハイライトする見出しの位置を指定することができます。50%にすると真ん中に固定されます。(目次がスクロールできる場合のみ)

ハイライト色、背景色はテーマに合わせて好きな色に変更してください。ここではTHE SONICデフォルトカラー(#00b1c3)に合わせています。

クリックしてカラーコードを調べよう

目次をスタイリッシュに

見出しの前にマークと、縦線がつきます。

/*--------------------------------------
サイドバー目次ハイライト
--------------------------------------*/
.mkj-side-style .mkj-content-in {
	max-height: 400px; /*目次の高さ*/
    overflow-y: scroll;
    scroll-padding: 20% 0; /*ハイライトする見出しの位置*/
}
.mkj-side-style .mkj-list li > .mkj-active { /*見出し色*/
	color: #02B1C3;
}
.mkj-side-style .mkj-list.mkj-list-nonum > li:before { /*ドットの場合*/
    background: #fff;
    border: 2px solid #02B1C3;
    top: 10px;
}
.mkj-side-style .mkj-list > .mkj-marker::before,
.mkj-side-style .mkj-list.mkj-list-nonum > .mkj-marker::before  { /*見出し丸*/
	color: #fff;
    background: #02B1C3;
}
.mkj-side-style .mkj-list > li:before{
    top: 4px;
    background: #fff;
    border: 2px solid #02B1C3;
    color: #02B1C3;
    /* border-radius: 50%; */
}
/*目次縦線*/
.mkj-side-style .mkj-list > li:not(:last-child):after {
	content:"";
	width: 3px;
    background: rgba(2,177,195, .1);
    border-color: #fff;
	display: block;
	position: absolute;
	top: 31px;
	bottom: -9px;
	left: -17.5px;
}
.mkj-side-style .mkj-list-nonum > li:not(:last-child):after {/*ドットの場合*/
	top: 26px;
	bottom: -10px;
	left: -13.5px;
}
.mkj-side-style .mkj-list > li.mkj-marker::after { /*縦線*/
	background: #02B1C3;
}
@media (max-width:1029px) {
	.widget_tsnc_table_of_contents {
		display: none;
	}
}

このカスタマイズを使うにはさきほど追加したstyle.cssのコードは削除して、こちらのコードに差し替えます。

最新のコードは Githubで管理してます。

参考URL

目次スクロール

この記事が気に入ったら
フォローしてね!

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

気になるガジェットやサービスをレビュー!日常生活のアップデートを目標に役に立つ情報を掲載していきます。

仕事のご依頼などはお問い合わせからどうぞ。

コメント

コメント一覧 (3件)

  • リンクありがとうございます。
    31行目 focus(); →mkjHighlight();です。
    onloadタイミングでも一度実行しておかないと、読み込み直後のハイライトが行われません。
    もちろん、スクロールタイミングでは問題ありません。

    Cookbookより。

    • Cookbook-かもさん。 さま

      記事を参考にさせていただきました!
      コードの確認までしていただきありがとうございます。

      早速修正させて頂きます。

  • はじめまして。とても参考になる記事有難うございます!
    しかし、当方の環境だと問題が発生してしまいました……。

    The SONICにて上記のコードをコピペをしてみたのですが、「functions.php(自動スクロールアリver)」を使うと、画面内に目次が残ろうとしてしまいます。

    たとえば、記事のフッタまで見に行くことができません。
    ハイライトされた目次が表示されるラインまで、強制的に上へ引き戻されてしまう感じです。

    あまり知識がなく、当方の環境によるものだったら大変申し訳無いのですが、もしよろしければZIMA様も一度お試し頂けないでしょうか?

目次