記事の表示位置に合わせて、サイドバーに設置した目次の見出しをハイライトするカスタマイズです。(PCのみ)
また、目次が自動でスクロールするので、現在記事のどこを見ているのか分かりやすくなります。
THE SONIC (動作デモ)
Microsoft Edge、Internet Explorer では目次スクロールが動作しないことを確認しました(見出しハイライトはOK)。自動スクロールはChrome、Firefox のみの対応となります。
サイドバーウィジットに目次を追加
まだウィジットに目次を追加していない場合は追加します。
「WordPress管理画面 > 外観 > ウィジット」を開いて
「THE SONIC 目次」を ドラッグアンドドロップ して 「(PC)追尾サイドバー」に追加しましょう。
PCで右側に固定表示される目次です。
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 の数字部分を小さくすると、目次の縦幅が短くなります。
そして、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で管理してます。
コメント
コメント一覧 (3件)
リンクありがとうございます。
31行目 focus(); →mkjHighlight();です。
onloadタイミングでも一度実行しておかないと、読み込み直後のハイライトが行われません。
もちろん、スクロールタイミングでは問題ありません。
Cookbookより。
Cookbook-かもさん。 さま
記事を参考にさせていただきました!
コードの確認までしていただきありがとうございます。
早速修正させて頂きます。
はじめまして。とても参考になる記事有難うございます!
しかし、当方の環境だと問題が発生してしまいました……。
The SONICにて上記のコードをコピペをしてみたのですが、「functions.php(自動スクロールアリver)」を使うと、画面内に目次が残ろうとしてしまいます。
たとえば、記事のフッタまで見に行くことができません。
ハイライトされた目次が表示されるラインまで、強制的に上へ引き戻されてしまう感じです。
あまり知識がなく、当方の環境によるものだったら大変申し訳無いのですが、もしよろしければZIMA様も一度お試し頂けないでしょうか?