MENU
HOME
TOP

WordPressプラグインなし 開閉式の目次をjQueryで自動表示する

目次を自動で表示してくれる便利なプラグインは、Table of Contents Plus なものが WordPress では有名ですが、、出来るだけプラグイン使わない系が流行ってるはずです。たぶん

んなわけで、今回はjQueryで自動表示する目次を作ってみました。

コードの編集に慣れてない方でもコードをコピペするだけで実装出来ますので、ぜひ導入を!(カップラーメンが出来る3分程度お時間かかります。)

目次の表示用のファイルを作成

まずは、目次表示用のjQeryとcssをテーマに追加していきます。

toc.jsの作成

とりあえず、以下のコードをテーマのディレクトリーにtoc.jsとでも名前を付けておいて保存します。

jQuery(function($) {
    var idcount = 1;
    var toc = '';
    var currentlevel = 0;
    jQuery("#entry-content h2,#entry-content h3", this).each(function() {
        this.id = "toc-" + idcount;
        idcount++;
        var level = 0;
        if (this.nodeName.toLowerCase() == "h2") {
            level = 1;
        } else if (this.nodeName.toLowerCase() == "h3") {
            level = 2;
        }
        while (currentlevel < level) {
            toc += "<ol class='toc-contents'>";
            currentlevel++;
        }
        while (currentlevel > level) {
            toc += "</ol>";
            currentlevel--;
        }
        toc += '<li><a href="#' + this.id + '">' + jQuery(this).html() + "</a></li>\n";
    });
    while (currentlevel > 0) {
        toc += "</ol>";
        currentlevel--;
    }
    if (jQuery("#entry-content h2")[0]) {
        jQuery("#toc").html('<div class="label">目次</div>'+ toc);
    }
});
//トグルはこんな感じで
// 目次表示切替
jQuery(function() {
    jQuery('.icon-a').click(function(){
        jQuery('.toc-contents').slideToggle('400');// slow表示 (slow)は600ミリ秒(fast)は200ミリ秒 任意の数値でも。
        // 表示非表示のクラス切替
        jQuery('.icon-a').toggleClass('icon-b');//「非表示」を「表示」になるように変更
    });
});

5行目の部分に注意です。#entry-contentで囲まれてる前提でいきますので以下のh2,h3の見出し部分は、お使いのテーマで記事部分の親要素の見出しを指定する必要があります。

jQuery("#entry-content h2,#entry-content h3", this)

スタイルシートの追加

以下のスタイルをstyle.cssに追加します。

#toc{
  margin: 30px 0;
  padding: 0;
  border-radius: 3px;
  display: table;
}
.label,.toc-contents{
  width: 100%;
  margin: 0;
  border-radius: 3px;
}
.label{
  text-align: center;
  font-weight: bold;
  background-color: #e9e9e9;
  background-image: -ms-linear-gradient(bottom,#ddd,#e9e9e9);
  background-image: -moz-linear-gradient(bottom,#ddd,#e9e9e9);
  background-image: -o-linear-gradient(bottom,#ddd,#e9e9e9);
  background-image: -webkit-linear-gradient(bottom,#ddd,#e9e9e9);
  background-image: linear-gradient(bottom,#ddd,#e9e9e9);
  font-size: 16px;
  padding: 8px 22px;;
  position: relative;
  color: #333;
  min-width: 250px;
  box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.29);
  -moz-box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.29);
  -webkit-box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.29);
}
.icon-a,.icon-b{
  width: 60px;
  height: 22px;
  margin: auto 0;
  position: absolute;
  cursor: pointer;
  top: 0;
  bottom: 0;
  right: 10px;
  background: #fff;
  border-radius: 5px;
  background-color: #eee;
  background-image: -ms-linear-gradient(bottom,#e3e3e3,#fff);
  background-image: -moz-linear-gradient(bottom,#e3e3e3,#fff);
  background-image: -o-linear-gradient(bottom,#e3e3e3,#fff);
  background-image: -webkit-linear-gradient(bottom,#e3e3e3,#fff);
  background-image: linear-gradient(bottom,#e3e3e3,#fff);
  box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.29);
  -moz-box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.29);
  -webkit-box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.29);
}
.icon-a::before,.icon-b::before{
  display: block;
  position: absolute;
  color: #555;
  font-size: 14px;
  width: 60px;
  height: 22px;
  top: 0;
  right: 0;
}
.icon-a::before{
  content: "非表示";
}
.icon-b::before{
  content: "表示";
}
.toc-contents{
  background: #fff;
  font-size: 14px;
  padding: 22px;
  min-width: 250px;
  box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.29);
  -moz-box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.29);
  -webkit-box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.29);
}
#toc li,#toc li a{
  font-size: 15px;
}
#toc li a{
  text-decoration: underline;
}

functions.phpにコードの記述

以下をfunctions.phpに追記します。

toc.jsの読み込み

function theme_enqueue_scripts() {
        wp_enqueue_script( 'toc-js', get_template_directory_uri() . '/toc.js' );
}
add_action( 'wp_enqueue_scripts', 'theme_enqueue_scripts' );

表示する場所の記述

これで初めの見出し(h2)上に表示されます。

function add_ads_before_1st_h2($the_content) {
  if (is_single()) {
    //広告(AdSense)タグを記入
    $ads = <<< EOF
<div class="label">目次</div>
EOF;
    $h2 = '/<h2.*?>/i';//H2見出しのパターン
    if ( preg_match( $h2, $the_content, $h2s )) {//H2見出しが本文中にあるかどうか
      $the_content  = preg_replace($h2, $ads.$h2s[0], $the_content, 1);//最初のH2を置換
    }
  }
  return $the_content;
}
add_filter('the_content','add_ads_before_1st_h2');

このコードは寝ログさんの記事からお借りしました。m(__)m

ちょっとコードの説明

before(疑似要素)に付けたクラスを.toggleClassで追加・削除する事で表示・非表示の再現してます。

ここをアイコンなどに変えると、デザイン的におしゃれになるかなと思いますので、自分でも色々試してみてください。

センターに表示する場合

デフォルトでは、tocの要素をこの様に指定していますが、

#toc{
  margin: 30px 0;
  padding: 0;
  border-radius: 3px;
  display: table;
}

以下のように、marginにautoを指定するだけで、センター表示になります。

#toc{
  margin: 30px auto 0;
  padding: 0;
  border-radius: 3px;
  display: table;
}

See the Pen toc test centering by kenji31 (@kenji31) on CodePen.

最初から閉じておく場合

ちなみに最初から閉じておきたい場合もあるので、コンテンツ部分の

.toc-contents を display: none;

としておいて非表示にしておくとこの様に最初は非表示になります。

See the Pen toc test first non-display by kenji31 (@kenji31) on CodePen.

だけど、このままだとコンテンツ部分が非表示なのに、ボタンのとこが非表示になってしまっているので、以下のように

.icon-a::before{
content: "非表示";
}
.icon-b::before{
content: "表示";
}

となっているcontent部分を以下のように逆にしてあげます。

.icon-a::before{
content: "表示";
}
.icon-b::before{
content: "非表示";
}

aとbのcontent:部分を反対にすればオッケーでーす。☆⌒d(´∀`)ノ

See the Pen toc test first non-display2 by kenji31 (@kenji31) on CodePen.

まとめ

どうでしょうか??特に読み込みミスがなければ、無事に表示されてるかと思います。

余計なプラグインが一つ無くなり、よく言えば 一石二鳥でございます。( ´∀`  )

スタイルは適当な物ですが、好みに合わせてスタイリングしてみてください。

また何か良い物があれば紹介したいと思います。
それでは、またお会いしましょう!!(`・ω・´)ゞ

スポンサーリンク

Profile

閲覧どうもありがとうございます。 ネット系で気になったことや、やってみたことをゆる~く配信してます。 まだまだ初心者なので、、お見苦しいとこがありますが、どうぞよろしく。

コメントを閉じる

コメントを残す

メールアドレスが公開される事はございませんが*の付いている欄は必須項目となります。
なおコメントの反映にお時間がかかる場合があります事をご了承ください。