Bloggerで目次を出すスクリプトを、適用先に合わせてカスタマイズする

Bloggerには目次を出す機能がない。

なのでカスタマイズが必要だが、定番の方法はJavascriptで記事の見出しから目次を自動生成する方法だろう。

見出しをつけて記事を書くだけで目次化できるのでこれは楽ちんだ。

ネットにはそういうコードを発表してくれてる人があちこちいるので、自分も基本的にコピペで目次生成に成功した。

ただ本来のコードは(この記事の目次のように)項番が自動付与されるのだが、それが適用先のブログの見出しのフォーマットに合わなかった。

なので少しコードをいじってこのような↓目次を出している。


適用先のブログの状況によって他にも細かなカスタマイズが必要にもなった。

今回はそのへんのカスタマイズも含め、Bloggerへの目次の導入につきまとめてみたい。


目次を自動生成するJavascript

自分は以下の記事を参考に目次を導入した。


>> Bloggerで目次と見出し番号を自動生成させるカスタマイズ方法 - 人気のあるBloggerブログの作り方


通常は↑に書かれているコードを、テーマのHTMLの


</head>の上


に挿入しておけばよろしい。

その上で記事のほうで目次を出したいところに<!--more-->タグを入れておく。

これはBloggerのエディタの「追記の区切りを挿入」アイコン(紙を真ん中で破いたみたいなの)を押せば良い。

これ↑

それだけで


  • 記事の見出し(hタグのところ)に項番を付けて、
  • なおかつその項番付きの目次を自動生成し、
  • moreタグ(区切り)のところに生成した目次を挿入


してくれる。

目次導入先のブログの問題点

というわけで上記の記事にある目次コードを既存のブログ「希望の苗を植えてゆく」に導入することにした。

しかしやってみると、


  • 大見出しの表記
  • 記事中広告の挿入方法
  • トップページに記事本文が出ている


の3点が問題となった。

大見出しの表記

まず上記ブログでは、

大見出しに「■」を付けて記事を作成

していたため、そこに項番を付けるとこのように、


大見出しと、それを元にした目次がおかしなことになってしまう。

記事中広告とバッティング

また同ブログではmoreタグを記事中広告の挿入場所として使っていた。
詳しくはこちら↓


>> Bloggerでタイトル下・記事中・記事下にAdsense広告を出す、その仕組みと実際の手順


しかし上記のJavascriptもmoreタグを挿入場所として使っている。

よってコードをそのまま使うと、


全記事の記事中広告のところに目次が挿入されてしまう


ことになるのであった。

ちなみにだいたい記事の真ん中あたりで、そりゃないぜセニョリータである(^_^;)

トップページに出ている目次が崩れる

また同ブログは古いテーマなこともあり、


  • トップページに記事がいくつか縦に並び
  • 各記事の本文がそのまま出ている


という昔懐かしいブログの仕様となっている。

しかし上記Javascriptはページ内の見出しを全部読み取って目次化する。

するとどうなるかというと、


  • トップページに出ている記事には、
  • トップページに出ているいくつかの記事の全見出しを拾った目次が表示される


という悲しい状態となる(´;ω;`)

目次生成の要件と実際のコード

上記の


  • 大見出しの■の前に項番が出て変(^_^;)
  • 記事中広告のところに目次が出てしまう
  • トップページの目次がおかしくなる


という問題を回避するため、少しコードをいじることにした。

ここではそのための要件と実際のコードを紹介する。

目次コードの要件

既存のブログの状況を鑑みて、


  1. 項番を付けないようにする
  2. moreタグ以外のところに目次を挿入する
  3. トップページでは目次を出さない


という感じにしたいと考えた。

実際のコード

で、上記要件のためにカスタマイズしたコードがこれ↓


<!-- 目次 -->

<!-- Topには表示が崩れるので目次を出さない -->
<!-- Topでないときだけ目次を出す -->

<b:if cond='data:blog.url != data:blog.homepageUrl'>

<script type='text/javascript'>
  //<![CDATA[
  if (typeof(jQuery) == 'undefined') {
    document.write("<scr" + "ipt type=\"text/javascript\" src=\"//ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js\"></scr" + "ipt>");
  }
  //]]>
</script>
<script type='text/javascript'>
  //<![CDATA[
  $(document).ready(function() {
    console.log("call func");
    $('a[name="mokuji"]').after("<div id='toc' />");
    var idcount = 1;
    var h2cnt = 0;
    var h3cnt = 0;
    var h4cnt = 0;
    var toc = '';
    var currentlevel = 0;
    $(".post-body h2,.post-body h3,.post-body h4", this).each(function() {
      var chapid = "chapter-" + idcount;
      $(this).before("<div class='chapter-no' id='" + chapid + "' />");
      idcount++;
      var level = 0;
//      var chapNo;
      if (this.nodeName.toLowerCase() == "h2") {
        level = 1;
        h2cnt++;
        h3cnt = 0;
        h4cnt = 0;
//        chapNo = h2cnt + ".";
      } else if (this.nodeName.toLowerCase() == "h3") {
        level = 2;
        h3cnt++;
        h4cnt = 0;
//        chapNo = h2cnt + "-" + h3cnt + ".";
      } else if (this.nodeName.toLowerCase() == "h4") {
        level = 3;
        h4cnt++;
//        chapNo = h2cnt + "-" + h3cnt + "-" + h4cnt + ".";
      }
      if (currentlevel == level) {
        toc += "</li><li>";
      }
      while (currentlevel < level) {
        toc += '<ul class="chapter"><li>';
        currentlevel++;
      }
      while (currentlevel > level) {
        toc += "</li></ul><li>";
        currentlevel--;
      }
      toc += '<a href="#' + chapid + '">' + $(this).text() + "</a>";
//      toc += '<a href="#' + chapid + '">' + chapNo + $(this).text() + "</a>";
//      $(this).html(chapNo + $(this).html());
    });
    while (currentlevel > 0) {
      toc += "</li></ul>";
      currentlevel--;
    }
    if ($(".post-body h2")[0]) {
      $("#toc").html(toc);
    } else {
      $('#toc').attr('class', 'no-toc');
    }
  });
  //]]>
</script>
<style><!--
  /*  目次のデザイン  */
  #toc:before{
    content:"目次";/*目次のタイトル*/
    padding-left:1em;
    font-weight:800;
  }
  #toc{
    background-color:#f9f9f9; /*目次の背景色*/
    padding:0em;
padding-top:1em;
    display:block;
    margin:1em 0;
    border:1px solid #e6e6fa;/*目次の枠線*/
  }
  #toc li{
margin-top:0.2em;
list-style:none;
margin-bottom:0.2em;
}
  #toc ul{
margin-bottom:1em;
padding-left: 2em;
}
  #toc:before{display:block;text-align:center;}
  .chapter-no{position: relative;top:-5em;}


--></style>

</b:if>

<!-- 目次ここまで -->


詳細は以下に説明する。

目次生成コード、カスタマイズのポイント

ここでは上記コードを理解し、自分なりにカスタマイズするときのヒントとなるよう、


  1. 項番を付けない
  2. moreタグ以外のところに目次を挿入する
  3. トップページでは目次を出さない


カスタマイズにつき説明しておく。

項番生成の抑止

まず項番生成をしないカスタマイズについて。

上記のカスタマイズしたコードを参考記事にある元のコードと見比べるとわかるが、


//でコメントアウトされている行

が項番を生成している箇所だ。

chapNoに項番を生成し、目次の各行を組み上げて入れてあるtoc内の文字列に繋げているので、そこんとこを削除している。

moreタグ以外のところに目次を挿入

また

$('a[name="mokuji"]').after("<div id='toc' />");

の行のmokujiのところはもともとmoreだった。

つまりmoreタグのかわりにmokujiというnameを探してそこに挿入するようカスタマイズしている。

で、記事のほうではHTMLに、

<a name='mokuji'></a>

と入れておけば、そこに目次が挿入される。

ちなみにBloggerの投稿編集画面で見るHTMLではmoreタグは

<!--more-->

となっているが、実際の記事のソースを見ると、その部分が

<a name='more'></a>

に変わっている。

よって元コードでは、アンカータグのnameのmoreをめがけて目次を挿入してるのである。

なのでコードのほうで変えた文字列('mokuji')をアンカータグのnameにしておけばそこに目次が挿入されるというわけだ。

トップページの目次表示抑止

そして最後、トップページでは目次を出さないようにするカスタマイズ。

これは単純で、「トップページじゃないときだけ」というif文で全体を囲うだけ。

<b:if cond='data:blog.url != data:blog.homepageUrl'> 
目次生成コード 
</b:if>

って感じになっている。

他のブログでも使用可能

上記のいじったJavascriptはブログ「希望の苗を植えてゆく」に導入したのだが、その後もう1つのカンボジアブログでもまた少し変えた上で導入している。

普通に動いているので、たぶんどこに入れても大丈夫そうだ。
上記のカスタマイズを参考に、自分の状況に合わせいじってみてもいいかもしれない。


とはいえ使う場合はあくまで自己責任で。
自分が導入するときそうだったように、状況によっていろいろ問題は出ると思う。

ちなみにこのブログでは元コードのまま使用していて、だから目次にも見出しにも項番が出ているはずだ(出てるよね?w)。

そして最後に、元コードを開発し公開してくれた方に感謝します m(_ _)m


その他のコード改変によるカスタマイズはこちら

コメント

このブログの人気の投稿

Bloggerでタイトル下・記事中・記事下にAdsense広告を出す、その仕組みと実際の手順

Emporio、テーマデザイナーでできるオススメ設定

極私的・各Bloggerテーマの使いみち~情報サイト・ポートフォリオ・日記~