Amazonで1000円分もらえるチャンス

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

7 min

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

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

動作確認テーマ
注意点

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

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

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

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

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

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

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

functions.php に追記

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

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

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' );

見出しハイライトのみで、目次の自動スクロールが不要な場合はこのコードをご利用ください。全体的に見出し数が少ないのであればこちらのほうがおすすめです。

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 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');
    });
};
focus();
window.addEventListener("scroll", mkjHighlight);
</script>
EOM;
}
add_action( 'wp_print_footer_scripts', 'mkj_highlighter' );

style.css に追記

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

子テーマ内の 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)に合わせています。

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

目次をスタイリッシュに

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

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: #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

ZIMA

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

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

FOLLOW

カテゴリー:
関連記事

2 件のコメント

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

    Cookbookより。

    • Cookbook-かもさん。 さま

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

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

コメントを残す

メールアドレスが公開されることはありません。