対象読者
- WordPressテーマ「Cocoon」ユーザーの方
- この件をやろうといろいろコピペしてみたが、失敗した方
結論
WordPressでは、記事上部に目次を自動生成できる。しかし、スクロールすると、折角の目次がフェードアウトしてしまい、記事構造や現在位置が分からなくなってしまう。
そこで、
- 目次をサイドバーに追従させ、
- スクロール位置に応じてハイライトさせる
ことで、UXを高めることができる。私のサイドバーの目次を確認していただきたい(デスクトップ限定)。
以下では、これを実現するための手順や補足を説明する。
手順
2つの手順から成る。
- サイドバー追従の目次の設定
- それをハイライトさせる処理の記述
それぞれの具体的手順は以下だ。
- WordPressの管理画面 -> 外観 -> ウィジェット にて、サイドバースクロール追従に「[C]目次」を追加(詳細は参考1)
- WordPressの管理画面 -> 外観 -> テーマエディター にて、style.css、javascript.jsに追記(後述のコードをコピペ)
以下では、手順2のコピペ用コードを示す(元にしたのは参考1のコード)。
style.cssへのコピペ
a.current {
background-color: #EEEEFF;
}
a要素のclass名は何でもいいが、javascript.jsのclass名と対応させる必要がある。
javascript.jsへのコピペ
const GAP = -50;
const CLSNAME = "current" //cssと対応
class SidebarTOC{
constructor(selector){
this.$a = $(`${selector} a`);
}
getCurrentAnchor(currentTop){
var heads = this.getHeads();
var tops = heads.map(x => x.offset()["top"]);
var n_anchor = tops.length - 1;
for(var i=0; i < n_anchor; i++){
let first = tops[i] + this.GAP;
let second = tops[i + 1] + this.GAP;
if(first < currentTop && currentTop < second){
return $(this.$a[i]);
}
}
}
getHeads(){
var arr = [];
this.$a.each(function(_, a){
var href = $(a).attr("href");
arr.push($(href));
});
arr.push($(".article-footer"));
return arr;
}
clear(){
this.$a.removeClass(CLSNAME);
}
inRange(currentTop){
var tops = this.getHeads().map(x => x.offset()["top"]);
var min = tops.reduce((a, b) => a < b ? a: b);
var max = tops.reduce((a, b) => a > b ? a: b);
return min < currentTop && currentTop < max + this.GAP;
}
}
$(function(){
//引数は人によって異なるかも
//サイドバー目次の属性をF12で確認してください
var toc = new SidebarTOC("#sidebar-scroll .toc-content");
$(window).on('load scroll', function() {
toc.clear();
var wTop = $(window).scrollTop();
if(toc.inRange(wTop)){
toc.getCurrentAnchor(wTop).addClass(CLSNAME);
}
});
});
このコードはCocoonではないWordPressテーマでも使えると思う。結局、似たような処理をしているし、私のコードの方が整理されているからだ(参考2)。
プラグインTOC+(Table Of Content Plus)による悪影響
私の環境では、目次生成用のプラグインTOC+が入っていた。使っていなかったけど。
見出し要素には、自動でIDが付与されるが、{i, i-2, i-3, …}のようにちょっと不規則に与えられていた。そのせいで、試行錯誤が困難なものとなった。
いくつかの自分の記事をチェックすると、正しく動作しないものがあった。[F12]で確認すると、このような規則に従っていないIDが発見された。
しかし、TOC+を削除すると、IDが規則正しく与えられるようになった。
原因はWordPressテーマの仕様なのか、それとプラグインの干渉なのか、分からない。変なことが起こっている場合、プラグインを掃除するといいかもしれない。
コピペカスタマイズの困難さ
私もまずはいろいろググって、コードをコピペしてみたが、正常に動かなかった。
- JavaScriptを編集
- ブラウザの開発ツールを[F12]キーで開きつつ、自分の記事を確認
を繰り返し、遂に動作させることができた。
人ごとに環境が異なるため、コードを修正する必要があるかもしれない。故に、処理が分離してあり、理解しやすいコードじゃないと苦労する。
私のコードはまあまあ分かりやすく書けていると思う。letとvarが混在していてキモかったりするけどw。
処理を分離することの重要さや綺麗なコードを書く方針について、以下の記事にまとめたので、是非、参考にしてくだされ。
コメント