ブログには使われることが多い「目次」を、ページ内の h
タグを取得して表示させます。この動的なものを、ネイティブのJavaScriptで実装してみます。
.createElement()
JavaScriptの.createElement()
は、HTMLを動的生成するメソッドです。
var element = document.createElement(tagName[, options]);
tagNameには div
や a
などの HTML 要素名を指定することで生成できます。
createElement()
メソッドについての詳しくは以下の記事も参考にご覧ください。
記事内のhタグを取得した目次のサンプル
この記事本文内の見出しにあたる h
タグを全て取得して、取得した見出しの文字列を li
タグで出力します。
出力した li
タグのclassに、取得した見出しタグがつきます。例えば h2
の場合、classはh2です。
各目次をクリックすると、それぞれに対応した見出しタグにジャンプします。
サンプルのコード
目次を出力させるには、設置したい位置に以下のHTMLを記述します。
<ul id="tocBlock"></ul>
HTMLはこの一文のみでOKです。
var headings
には、目次で取得するタグを記述します。サンプルのコードでは、.entry-content h1
〜 .entry-content h6
を取得するように記述しています。
document.addEventListener('DOMContentLoaded', function() {
htmlTableOfContents();
} );
function htmlTableOfContents( documentRef ) {
var documentRef = documentRef || document;
var toc = documentRef.getElementById("tocBlock");
var headings = [].slice.call(documentRef.body.querySelectorAll('.entry-content h1, .entry-content h2, .entry-content h3, .entry-content h4, .entry-content h5, .entry-content h6')); /* ここで目次で取得するタグを指定 */
headings.forEach(function (heading, index) {
var ref = "toc" + index;
if ( heading.hasAttribute( "id" ) )
ref = heading.getAttribute( "id" );
else
heading.setAttribute( "id", ref );
var link = documentRef.createElement( "a" );
link.setAttribute( "href", "#"+ ref );
link.textContent = heading.textContent;
var div = documentRef.createElement( "li" );
div.setAttribute( "class", heading.tagName.toLowerCase() );
div.appendChild( link );
toc.appendChild( div );
});
}
try {
module.exports = htmlTableOfContents;
} catch (e) {
}
そして、var div
には出力させるタグを記述します。このスニペットでは、<ul id="tocBlock"></ul>
の ul
タグの中に出力するので、li
タグで出力させる記述です。
CSS
CSSでは、表示・非表示などの出し分けを行わないので、見た目を整えるだけですが、目次に番号を振りたい場合には、counter-increment
プロパティを使えばOKです。
ul#tocBlock {
border: none;
margin: 0;
list-style: none;
padding: 0;
counter-reset: li;
}
ul#tocBlock li {
padding: 0 0 0 32px;
font-size: 1.1rem;
margin: 8px 0;
line-height: 1.6;
position: relative;
}
ul#tocBlock li:before {
position: absolute;
top: 50%;
left: 0;
font-weight: bold;
color: #f0db3f;
counter-increment: li;
content: counter(li);
background: #313131;
border-radius: 9999px;
transform: translateY(-50%);
width: 22px;
height: 22px;
display: flex;
align-items: center;
justify-content: center;
line-height: 22px;
font-size: 0.85rem;
}
ul#tocBlock li a {
padding: 5px 0;
display: inline-block;
color: #313131;
transition: all .3s ease;
}
上記はこの記事用のCSSですが、使うサイトによってカスタマイズして活用ください。