これはなに?
このコードは、Bloggerなどのブログのサイドバーに 目次(Table of Contents)を自動表示 するためのスクリプトです。
読者が記事を読みやすくなるだけでなく、ブログ全体の利便性も向上します。この目次の機能・特徴を紹介
- 自動生成:記事の見出しを自動で取得して目次を作成
- 階層表示:
<h3>は少しインデントされてサブ項目として表示 - サイドバー固定(追従):
- このスクリプトは「目次が設置されているガジェット」を認識して固定
- 記事をスクロールしても画面上部に追従し、常に目次が見える
- フッターに到達すると自動で停止して重ならないよう調整
- ハイライト:現在の表示位置に応じて目次項目が強調表示
- フッター衝突回避:サイドバーがフッターと重ならないように調整
コード
<div id="toc-custom-widget" class="toc-widget-container">
<div class="toc-label">CONTENTS</div>
<div id="toc-content-area" class="custom-toc-wrapper"></div>
</div>
<script type="text/javascript">
(function($){
$(window).on('load', function(){
var $postBody = $('.post-body, .entry-content, .item-post-inner').first();
var $tocArea = $('#toc-content-area');
var $widget = $('#toc-custom-widget');
var $parentGadget = $widget.closest('.widget');
if ($postBody.length === 0 || $tocArea.length === 0) return;
var $headings = $postBody.find('h2, h3');
if ($headings.length > 0) {
var $ul = $('<ul></ul>');
$headings.each(function(i, el){
var id = 'toc-point-' + i;
$(el).attr('id', id);
var li = $('<li></li>');
if(el.tagName === 'H3') li.css('padding-left','15px');
var a = $('<a href="#'+id+'" class="toc-link">'+$(el).text()+'</a>');
a.on('click', function(e){
e.preventDefault();
$('html, body').animate({scrollTop: $(el).offset().top - 90},500);
});
li.append(a);
$ul.append(li);
});
$tocArea.empty().append($ul);
$widget.css('visibility','visible'); // 描画完了後に表示
} else {
$parentGadget.hide();
return;
}
var offset = $parentGadget.offset().top;
var originalWidth = $parentGadget.width();
var $footer = $('#footer, footer, .footer-wrapper, #footer-wrapper').first();
function updateTocPosition(){
var scrollTop = $(window).scrollTop();
var windowWidth = $(window).width();
if(windowWidth > 768){
var footerTop = $footer.length ? $footer.offset().top : $(document).height();
var widgetHeight = $parentGadget.outerHeight();
var topPadding = 20;
var stopLimit = footerTop - widgetHeight - topPadding - 30;
if(scrollTop > offset){
if(scrollTop > stopLimit){
$parentGadget.css({
'position':'absolute',
'top': stopLimit+'px',
'width': originalWidth+'px',
'z-index':'99'
});
}else{
$parentGadget.css({
'position':'fixed',
'top': topPadding+'px',
'width': originalWidth+'px',
'z-index':'99'
});
}
}else{
$parentGadget.css({'position':'static','width':'auto'});
}
}else{
$parentGadget.css({'position':'static','width':'auto'});
}
// ハイライト
var activeId = "";
$headings.each(function(){
if($(this).offset().top < scrollTop + 120){
activeId = $(this).attr('id');
}
});
$('.toc-link').removeClass('active');
$('.toc-link[href="#'+activeId+'"]').addClass('active');
}
$(window).on('scroll resize', updateTocPosition);
updateTocPosition(); // 初回
});
})(jQuery);
</script>
設置方法
-
HTMLガジェットの追加
Bloggerの「レイアウト」→「ガジェットを追加」→「HTML/JavaScript」→ 上記の<div id="toc-custom-widget">…</div>と<script>を貼り付け - CSSはテーマに合わせて調整
- 色や幅、背景などを好みに変更可能
-
初期状態では目次が非表示になっている場合は
visibilityを確認 -
記事本文に
<h2>や<h3>を設定
目次はこれらのタグから自動生成される
コードの中から重要な点を解説
動的なID付与とリンク生成
$headings.each(function(i, el){ ... })
の部分で、記事内の見出しに
toc-point-0
から順にIDを自動で割り振っています。これにより、手動でアンカーを埋め込む手間を省き、目次クリック時の正確なジャンプを実現しています。
スマートな表示制限ロジック
if ($headings.length > 0)
で見出しの有無を判定し、見出しがない場合は
$parentGadget.hide()
によってガジェット枠ごと非表示にしています。これにより、サイドバーに「空のタイトル」だけが残る不格好な状態を防いでいます。
精密な追従・衝突回避計算
updateTocPosition
関数内の
stopLimit
計算が重要です。フッターの位置(footerTop)と自身の高さ(widgetHeight)を計算し、フッターに到達した瞬間に
fixed(固定)から
absolute(絶対配置)へ切り替えることで、フッターを突き抜けて重なる問題を回避しています。
読者の現在地を示すハイライト機能
スクロールに合わせて
スクロールに合わせて
activeId
を更新し、目次の該当リンクに
active
クラスを付与しています。これにより、ユーザーは「今、記事のどのあたりを読んでいるのか」を視覚的に把握できます。
注意点
- モバイル表示:幅768px以下では固定解除され、通常の位置に表示
- jQuery必須:このスクリプトはjQuery依存
- サイドバー幅:ウィジェット幅が自動計算されますが、テーマによっては調整が必要
- 読み込みタイミング:記事本文のレンダリング後に目次が生成されるため、初回表示が少し遅れる場合あり
- 複数目次:1ページに複数の同様の目次ガジェットは推奨されません
まつさん
目次が表示されてからサイドバーが固定される仕様にはなっているはずです。その仕様でサイドバーが効かないケースもあることをご了承ください。許してニャン🐱
目次が表示されてからサイドバーが固定される仕様にはなっているはずです。その仕様でサイドバーが効かないケースもあることをご了承ください。許してニャン🐱

0 件のコメント:
コメントを投稿