Bloggerブログ|開閉式の目次に変更|jQuery

もくじ リンク

投稿2019年5月11日 更新

 もくじを導入すると、目次と記事本文で、まったく同じ文が2回表示されるので、人によってはしつこく感じるかもしれません。
 そこでこのページでは、もくじを開閉できるように変更し、もくじに表示される文が目障りにならないようにしてみます。
 なお目次を開閉させるにあたって、以下の2つのパターンが考えられるので両方取り上げます。

 初めは目次を開いておいて、指定した場所がクリックされたら
 目次が閉じるようにする場合

 初めは目次を閉じておいて、指定した場所がクリックされたら
 目次が開くようにする場合


もくじ

 初めにもくじを開いておく場合



 以下のデモの一番上「もくじ【クリックすると閉じます】」と書かれているところをクリックすると、その場所だけ残して後の目次欄が隠れます。


記事中で設定した見出し(h2)
見出しではない文
見出し
見出しではない文
見出し見出し
見出しではない文


 ol(番号付きリスト)を使用する場合のjQueryのコード

<script>
//<![CDATA[
$(function(){
var toc = '<div class="toctitle">もくじ【非表示】</div><div id="open-close-area"><ol>';
var count = 0;
$('.post-body h2').each(function (){
count++;
this.id = 'chapter-' + count;
toc += '<li><a href="#' + this.id + '">' + $(this).html() + '</a></li>';
});
toc += '</ol></div>';
$('#toc').html(toc);
var $openclosearea = $('#open-close-area');
$('.toctitle').click(function(){
var $this = $(this);
if($openclosearea.css('display')== 'block'){
$openclosearea.slideUp('fast');
$this.html('もくじ【表示】')}
else{$openclosearea.slideDown('slow');
$this.html('もくじ【非表示】')}
});
});
//]]>
</script>

 ul(番号なしリスト)を使用する場合のjQueryのコード

<script>
//<![CDATA[
$(function(){
var toc = '<div class="toctitle">もくじ【非表示】</div><div id="open-close-area"><ul>';
var count = 0;
$('.post-body h2').each(function (){
count++;
this.id = 'chapter-' + count;
toc += '<li><a href="#' + this.id + '">' + $(this).html() + '</a></li>';
});
toc += '</ul></div>';
$('#toc').html(toc);
var $openclosearea = $('#open-close-area');
$('.toctitle').click(function(){
var $this = $(this);
if($openclosearea.css('display')== 'block'){
$openclosearea.slideUp('fast');
$this.html('もくじ【表示】')}
else{$openclosearea.slideDown('slow');
$this.html('もくじ【非表示】')}
});
});
//]]>
</script>

初めにもくじを閉じておく場合



 以下のデモの一番上「もくじ【クリックすると開きます】」と書かれているところをクリックすると、隠れている目次欄が表示されます。


記事中で設定した見出し(h2)
見出しではない文
見出し
見出しではない文
見出し見出し
見出しではない文


 ol(番号付きリスト)を使用する場合のjQueryのコード

<script>
//<![CDATA[
$(function(){
var toc = '<div class="toctitle">もくじ【表示】</div><div id="open-close-area"><ol>';
var count = 0;
$('.post-body h2').each(function (){
count++;
this.id = 'chapter-' + count;
toc += '<li><a href="#' + this.id + '">' + $(this).html() + '</a></li>';
});
toc += '</ol></div>';
$('#toc').html(toc);
var $openclosearea = $('#open-close-area');
$openclosearea.css('display','none');
$('.toctitle').click(function(){
var $this = $(this);
if($openclosearea.css('display')== 'block'){
$openclosearea.slideUp('fast');
$this.html('もくじ【表示】')}
else{$openclosearea.slideDown('slow');
$this.html('もくじ【非表示】')}
});
});
//]]>
</script>

 ul(番号なしリスト)を使用する場合のjQueryのコード

<script>
//<![CDATA[
$(function(){
var toc = '<div class="toctitle">もくじ【表示】</div><div id="open-close-area"><ul>';
var count = 0;
$('.post-body h2').each(function (){
count++;
this.id = 'chapter-' + count;
toc += '<li><a href="#' + this.id + '">' + $(this).html() + '</a></li>';
});
toc += '</ul></div>';
$('#toc').html(toc);
var $openclosearea = $('#open-close-area');
$openclosearea.css('display','none');
$('.toctitle').click(function(){
var $this = $(this);
if($openclosearea.css('display')== 'block'){
$openclosearea.slideUp('fast');
$this.html('もくじ【表示】')}
else{$openclosearea.slideDown('slow');
$this.html('もくじ【非表示】')}
});
});
//]]>
</script>

開閉欄の文字を変更するには



 デモではクリックするたびにもくじの一番上の表記が変わるようにしています。 この開閉欄は状況に応じて3つの表記を使い分けることができるので、変更する場合は以下の個所を変えてください。

一番初めに表示する文字を変える


 コード内の<div class="toctitle"></div>で囲まれた「もくじ【非表示】」と書かれたところが、画面を読み込んだときに一番初めに表示される文字になります。

var toc = '<div class="toctitle">もくじ【非表示】</div><div id="open-close-area"><ul>';

変更例
目次【閉じる】     目次【開く】
index【close】     index【open】
要約【開く】      要約【閉じる】
もくじで要約【開く】  もくじで要約【閉じる】


クリックされたときに表示する文字を変える


 以下の「もくじ【表示】」と書かれたところは、クリックされて目次が閉じたときに表示する文字です。
 さらにその下の「もくじ【非表示】」と書かれているところは、クリックされて目次が開いたときに表示する文字です。
 変更する際はクオテーションマーク ' ' の内側を変えてください。
' ' が消えないように注意です。

if($openclosearea.css('display')== 'block'){
$openclosearea.slideUp('fast');
$this.html('もくじ【表示】')}        閉じた時に表示する文字
else{$openclosearea.slideDown('slow'); 
$this.html('もくじ【非表示】')}       開いた時に表示する文字
});


fontawesomeのアイコンを挿入する


 疑似クラスを設定してアイコンを使用することもできますが、iタグを使うと張り付けるだけで済むので、ここではiタグを使った方法を取り上げます。もくじに使えそうなアイコンは以下の通りです。

(fontawesome5の場合)
 <i class="far fa-list-alt"></i>
 <i class="fas fa-columns"></i>
 <i class="fas fa-list-ol"></i>
 <i class="fas fa-list-ul"></i>
 <i class="fas fa-book"></i>
 <i class="fas fa-toggle-off"></i>
 <i class="far fa-file-alt"></i>
 <i class="fab fa-elementor"></i>
 <i class="fas fa-list"></i>
 <i class="far fa-edit"></i>
 <i class="fas fa-book-open"></i>
 <i class="fas fa-toggle-on"></i>


 fontawesomeの使用例として、本のアイコンをもくじに表示してみます。
iタグを貼り付ける場所は以下の3カ所です。

var toc = '<div class="toctitle"><i class="fas fa-book-open"></i> もくじ</div>

$openclosearea.slideUp('fast');
$this.html('<i class="fas fa-book-open"></i> もくじ')}
else{$openclosearea.slideDown('fast');
$this.html('<i class="fas fa-book"></i> もくじ')};


 クリックするたびにアイコンの形が変化します。


見出し
見出しではない文
見出し
見出しではない文
見出し見出し
見出しではない文


もくじのデザイン例 CSS



 目次のセレクターと適用するプロパティの例です。

#toc{/*もくじ全体のデザイン */
width:90%;/* もくじの幅:記事ページの幅に対する割合(%) */
display:inline-block;/* 文字の長さに合わせてフレキシブルにもくじの幅を変える場合 */
background:#f8f9fa;/*背景色 */
border:1px solid #a2a9b1;/* もくじの枠線:太さ 実線 色; */
border-radius:1px;/* 枠線の角に丸みをつける */
padding:7px;/* もくじ内の文字と、もくじの枠線までの距離 */
margin-top:7px;/* もくじの上にあるもくじの外の文や画像と、もくじの距離 */
margin-bottom:7px;/* もくじの下にあるもくじの外の文や画像と、もくじの距離 */
/* margin:7px auto; もくじ全体の位置を左右中央揃えにする場合*/
}
.toctitle{/*クリックする場所*/
font-size:17px;/* クリック部分の文字の大きさ */
cursor:pointer;/* マウスのカーソルが開閉部に乗った時に形を変える:指の形 */
user-select:none;/* 開閉部がクリックされた時の範囲選択:できないようにする*/
}
#open-close-area{/*クリックすると開閉する場所*/
}
#toc ol, #toc ul{
font-size:17px;/*もくじに生成するリストの文字の大きさ */
margin-top:1em;/*もくじに生成するリストと、上の開閉部までの距離:1文字分 */
margin-bottom:1em;/*もくじに生成するリストと、もくじの下の枠線までの距離 */
margin-left:1em;/*もくじに生成するリストと、もくじの左の枠線までの距離  */
}
#toc ol li, #toc ul li{/* もくじ内の各リスト */
background:inherit;/* 背景色:もくじ全体の背景色を引き継ぐ; 色を指定するとリストの背景だけに色が付く*/
padding-left:0em;/* 左のリスト番号(記号)と文字の距離 */
margin-top:0.25em;/* 上のリストとの距離 */
margin-bottom:0.25em;/* 下のリストとの距離 */
line-height:1.5em;/* 行の高さ */
}
#toc a{/*もくじに生成されるリストの最内はaタグ(ページ内リンク)*/
color:#19192d;/*リンク可能な文字の色を他で設定している場合にその色と違うものにするには指定*/
text-decoration: none;/* 下線:なし */
}


開閉欄の幅を変更するには



 スタイルシート(CSS)を変更します。
もくじ全体のスタイルを指定している#tocにwidthを設定し、数値で指定するか、displayを設定し、値に「inline-block」を指定します。

 以下のデモはinline-blockを使用したものです。
もくじが閉じている時は、開閉欄の文字の長さに合わせてもくじの幅が狭まり、もくじが開いている時は、もくじに生成されたh2の文字の長さに合わせて幅が広がります。

#toc{display:inline-block;}


見出し
見出しではない文
見出し
見出しではない文
見出し見出し
見出しではない文


 もくじにはdivタグを使用しており、divは初期値でブロック要素となるので、あえてCSSにblockを指定する必要はありませんが、blockを指定して、なおかつwidthを指定しないようにすると、文字の長さに関わらず開閉欄が横一杯に広がります。

#toc{
display:block;
text-align:center;/*文字の中央揃え*/
}


見出し
見出しではない文
見出し
見出しではない文
見出し見出し
見出しではない文


開閉アニメーションを変更する



 ここで紹介しているjQueryのコードは、シャッターを上げ下げするような動きでもくじの表示を切り替えています。
 これをふわっと浮き上がる感じに変えるには「slideDown」「slideUp」と書かれているところを、以下のように「fadeIn」「fadeOut」に変更します。
 大文字と小文字の違いは厳格に認識されるので、Iをi、Oをoとしないように注意してください。

$openclosearea.fadeOut('slow');
$this.html('<i class="fas fa-book-open"></i>index【open】')}
else{$openclosearea.fadeIn('500');
$this.html('<i class="fas fa-book"></i>index【close】')};


開閉スピードを変更する



 「fast」「slow」と書かれているところを、以下のように半角で「fast」「slow」もしくは数字に書き換えてください。

$openclosearea.slideUp('slow');
$this.html('<i class="fas fa-book-open"></i>index【open】')}
else{$openclosearea.slideDown(750);
$this.html('<i class="fas fa-book"></i>index【close】')};

 数字の場合はクオテーションマーク' 'を削除した上で記述してください。単位はミリ秒となり、1000と入力すると1秒、100とすると0.1秒でクリックしてからの動作が完了します。

もくじを導入する前にh2にidを設定している場合のコード



 今回紹介したもくじのコードを使用すると、自分で設定したh2のidが「chapter-○○」というid名に上書きされ、消えてしまいます。
「自分で設定したh2のid名が消えては困る」という場合は、以下のコードをご利用ください。

 初めにもくじを開いておく場合(ol)

<script>
//<![CDATA[
$(function(){
var toc = '<div class="toctitle">もくじ【非表示】</div><div id="open-close-area"><ol>';
var count = 0;
$('.post-body h2').each(function (){
count++;
if($(this).attr('id') == undefined){
this.id ='chapter-' + count;
}
toc += '<li><a href="#' + this.id + '">' + $(this).html() + '</a></li>';
});
toc += '</ol></div>';
$('#toc').html(toc);
var $openclosearea = $('#open-close-area');
$('.toctitle').click(function(){
var $this = $(this);
if($openclosearea.css('display')== 'block'){
$openclosearea.slideUp('fast');
$this.html('もくじ【表示】')}
else{$openclosearea.slideDown('slow');
$this.html('もくじ【非表示】')}
});
});
//]]>
</script>

 初めにもくじを開いておく場合(ul)

<script>
//<![CDATA[
$(function(){
var toc = '<div class="toctitle">もくじ【非表示】</div><div id="open-close-area"><ul>';
var count = 0;
$('.post-body h2').each(function (){
count++;
if($(this).attr('id') == undefined){
this.id ='chapter-' + count;
}
toc += '<li><a href="#' + this.id + '">' + $(this).html() + '</a></li>';
});
toc += '</ul></div>';
$('#toc').html(toc);
var $openclosearea = $('#open-close-area');
$('.toctitle').click(function(){
var $this = $(this);
if($openclosearea.css('display')== 'block'){
$openclosearea.slideUp('fast');
$this.html('もくじ【表示】')}
else{$openclosearea.slideDown('slow');
$this.html('もくじ【非表示】')}
});
});
//]]>
</script>

 初めにもくじを閉じておく場合(ol)

<script>
//<![CDATA[
$(function(){
var toc = '<div class="toctitle">もくじ【表示】</div><div id="open-close-area"><ol>';
var count = 0;
$('.post-body h2').each(function (){
count++;
if($(this).attr('id') == undefined){
this.id ='chapter-' + count;
}
toc += '<li><a href="#' + this.id + '">' + $(this).html() + '</a></li>';
});
toc += '</ol></div>';
$('#toc').html(toc);
var $openclosearea = $('#open-close-area');
$openclosearea.css('display','none');
$('.toctitle').click(function(){
var $this = $(this);
if($openclosearea.css('display')== 'block'){
$openclosearea.slideUp('fast');
$this.html('もくじ【表示】')}
else{$openclosearea.slideDown('slow');
$this.html('もくじ【非表示】')}
});
});
//]]>
</script>

 初めにもくじを閉じておく場合(ul)

<script>
//<![CDATA[
$(function(){
var toc = '<div class="toctitle">もくじ【表示】</div><div id="open-close-area"><ul>';
var count = 0;
$('.post-body h2').each(function (){
count++;
if($(this).attr('id') == undefined){
this.id ='chapter-' + count;
}
toc += '<li><a href="#' + this.id + '">' + $(this).html() + '</a></li>';
});
toc += '</ul></div>';
$('#toc').html(toc);
var $openclosearea = $('#open-close-area');
$openclosearea.css('display','none');
$('.toctitle').click(function(){
var $this = $(this);
if($openclosearea.css('display')== 'block'){
$openclosearea.slideUp('fast');
$this.html('もくじ【表示】')}
else{$openclosearea.slideDown('slow');
$this.html('もくじ【非表示】')}
});
});
//]]>
</script>

付け加えたコード



if($(this).attr('id') == undefined){ this.id ='chapter-' + count; }

 このコードの意味は、
「もしh2にidが設定されていないなら、id名をchapter-1 chapter-2 chapter-3 ・・・とする」ということを表しています。

詳しいことは以下の記事で取り上げています。
【Bloggerブログ】見出しに付けたid名を利用して目次を生成するためのコード【jQuery】

もくじを利用するために



こちらで紹介しているもくじを利用するには4つの手順が必要です。

1 以下のjQueryのCDNを</head>の上に貼り付ける
 (すでにjQueryを使用中の場合はこの作業は不要です)
「テーマ」→「HTMLを編集」をクリックし、</head>の上に貼り付けてください。

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js"/>

2 次項から挙げるjQueryのコードを</body>の上に貼り付ける
 用途に合わせてコードを選んでください。

3 もくじのデザインを]]></b:skin>の上に指定する
 検索欄に]]></b:skin>と打ち込んで、その上にもくじのスタイルを指定してください。
 Bloggerブログでは、]]></b:skin>より上のエリアがスタイルを指定する場所となっています。
 このページでは、もくじのセレクターを指定する際の参考になるように、一つだけCSSの例を挙げていますが、スタイリッシュなデザインは用意していませんので、ご自身のセンスでデザインしてください。

4 記事ページのHTMLに<div id="toc"></div>と記述する
 <div id="toc"></div>を記述した場所にもくじが表示されます。
もくじを表示するために毎回このコードを記述するのは面倒という場合は、コードをテンプレート化することもできます。
 詳しい手順は毎回記述せずに済ませる方法で取り上げています。

 より詳しい目次の導入方法は以下で画像を使って取り上げています。
記事中のh2を利用して目次を自動生成する(ページ内リンク)

QooQ