- Published on
WordPressで目次を作成してサイドバーに固定する方法【プラグインなし】
目次
記事をスクロールしても横に目次が固定されるやつです。
プラグインを使わず目次を作成してスクロールしても目次をサイドバーに固定してみます。
興味のあるかたは使ってみてください。
完成した見た目
確認に使ったテーマはTWENTYSIXTEENです。
目次のスクリプト
footer.phpのbody直前に追記します。
...省略
<!-- ここから目次作成スクリプト -->
<script>
const indexWrap = document.querySelector('.index_wrap'); //H2タグの前に挿入したdivタグ
if ( indexWrap ) {
let postContent = document.querySelector('.entry-content'); //記事本文が書かれているラッパー
let hTags = postContent.querySelectorAll('h2, h3'); //記事内のH2とH3タグを全て取得
if (hTags.length > 0) {
let indexList = document.createElement("ul");
let listSrc = "";
let h3List = ""; //h3タグを取得しておくための変数
for (let i = 0; i < hTags.length; i++) {
let theHeading = hTags[i];
theHeading.setAttribute('id', "index_id" + i); //リンクで飛べるようにIDをつける
if (theHeading.tagName === 'H2') {
if (h3List !== "") {
//h3リストが生成されていれば
listSrc += '<ul>' + h3List + '</ul>';
h3List = "";
}
listSrc += '</li><li><a href="#index_id' + i + '">' + theHeading.textContent + '</a>';
} else if (theHeading.tagName === 'H3') {
h3List += '<li><a href="#index_id' + i + '">' + theHeading.textContent + '</a></li>';
}
}
if (h3List !== "") {
//最後のリストがh3だった場合
listSrc += '<ul>' + h3List + '</ul></li>';
} else {
listSrc += '</li>';
}
indexList.innerHTML = listSrc;
indexWrap.appendChild(indexList);
}
}
</script>
<!-- ここまで目次作成スクリプト -->
</body>
</html>
参考サイトhttps://wemo.tech/67
コピペで大丈夫なんですが、本文を囲っている場所のクラス名なんかはテーマによって違ったりするので各自で確認しましょう。
let postContent = document.querySelector('.entry-content');
この場合は.entry-contentですが、enrty_contentだったりentry_postだったりテーマによって違いがあります。
ここが合ってないと動作しません。
これで目次を作成する用意ができまして、次に目次を表示させます。
position stickyでスクロールしてもサイドに固定する
サイドバーに表示するのですがスクロール量を計算してーとか面倒なことせず簡単な方法がありました。
cssで目次にposition: sticky;を使えば固定できるようです。
ただ少し罠がありまして、ここまでくると通常はウィジェットに目次を表示するためのタグ(コード)をおいて終わりかと思ったのですが違いました。
どうやら入れ子の状態だとうまく固定されないようです。
なのでウィジェットではなくsidebar.phpなどのサイドバーのファイルに直接かきます。
//sidebar.php
<?php if ( is_active_sidebar( 'sidebar-1' ) ) : ?>
<aside id="secondary" class="sidebar widget-area" role="complementary">
<?php dynamic_sidebar( 'sidebar-1' ); ?>
</aside><!-- .sidebar .widget-area -->
//ここ目次用の追加タグ
<div class="index_wrap sticky"><span>目次</span></div>
//ここまで目次用の追加タグ
<?php endif; ?>
ここでも注意ですが、 aside の中に入れる形だと入れ子になりうまく固定されません。
なので外にだしましょう。
これだけだとサイドバーのCSSが効かないので、サイドバー用のCSSを効かせます。
//cssの例
.sticky {
position: -webkit-sticky;
position: sticky;
/* ここからテーマに合わせて変更してください */
top: 10px;
float: left;
margin-left: 75%;
padding: 0;
width: 25%;
}
/* 目次というテキストのみためを変える場合の例*/
.index_wrap{
font-size:1.3rem;
padding:10px;
}
スマホで目次を非表示にする場合
@media screen and (max-width: 480px) {
.index_wrap{
display:none;
}
}
ざっと説明しましたが、クラス名が干渉したりするとデザインが崩れるのでご注意を。好きなように変更してください。