現在、JavaScriptで、文章中のh2、h3を拾い、自動で見出しを作るコーディングをしています。
下記サイトを参考に、コーディングをしました。
https://www.marorika.com/entry/create-toc
下記が、理想のアウトプットです。
【理想の形】 <div id="index"> <p class="toc-title">目次</p> <ul> <li><a href="#target-1">H2の内容</a></li> <li><a href="#target-2">H2の内容</a></li> <li><a href="#target-3">H2の内容</a></li> <li><a href="#target-4">H3の内容</a></li> <li><a href="#target-5">H3の内容</a></li> </li> <li><a href="#target-6">H2の内容</a></li> <li><a href="#target-7">H2の内容</a></li> </ul> </div>
ですが、現状は下記のようにアウトプットされてしまっています。
<div id="index"> <p class="toc-title">目次</p> <ul> <li><a href="#target-1">H2の内容</a></li> <li><a href="#target-2">H2の内容</a></li> <li><a href="#target-3">H2の内容 <li><a href="#target-4">H3の内容</a></li> <li><a href="#target-5">H3の内容</a></li> </a></li> <li><a href="#target-6">H2の内容</a></li> <li><a href="#target-7">H2の内容</a></li> </ul> </div>
現在のコードです。
document.addEventListener('DOMContentLoaded', function () { var contentsList = document.getElementById('index'); var ulWrapper = document.createElement('ul'); var matches = document.querySelectorAll('h2, h3'); matches.forEach(function (value, i) { var id = value.id; if(id === '') { id = value.textContent; value.id = id; } if(value.tagName === 'H2') { var li = document.createElement('li'); var a = document.createElement('a'); a.innerHTML = value.textContent; a.href = '#' + value.id; li.appendChild(a) ulWrapper.appendChild(li); } if(value.tagName === 'H3') { var li = document.createElement('li'); var a = document.createElement('a'); var lastUl = ulWrapper.lastElementChild; var lastLi = lastUl.lastElementChild; a.innerHTML = value.textContent; a.href = '#' + value.id; li.appendChild(a); lastLi.appendChild(li); } }); contentsList.appendChild(ulWrapper); });
<div id="index"> <p class="toc-title">目次</p> <!-- ここに目次が<ul><li></li></ul>の形で表示される --> </div> <div class="articleComponent"> <h2>H2の内容</h2> </div> <div class="articleComponent"> <p class="articleText">テキスト</p> </div> <div class="articleComponent"> <h2>H2の内容</h2> </div> <div class="articleComponent"> <p class="articleText">テキスト</p> </div> <div class="articleComponent"> <h2>H2の内容</h2> </div> <div class="articleComponent"> <p class="articleText">テキスト</p> </div> <div class="articleComponent"> <h3>H3の内容</h3> </div> <div class="articleComponent"> <p class="articleText">テキスト</p> </div> <div class="articleComponent"> <h3>H3の内容</h3> </div> <div class="articleComponent"> <p class="articleText">テキスト</p> </div> <div class="articleComponent"> <h2>H2の内容</h2> </div> <div class="articleComponent"> <p class="articleText">テキスト</p> </div> <div class="articleComponent"> <h2>H2の内容</h2> </div> <div class="articleComponent"> <p class="articleText">テキスト</p> </div>
どうしたら、入れ子にならず、ただh3の<li>を、h2の<li>の後に追加することができるでしょうか。どなたかお力をお貸しいただきたいです。
まず、理想形にあります、クラスに要素名はそもそもエラーの元になるのでやめましょう。
また、JavaScript処理を適用させようとしている元のHTMLも記載下さい。
でないと回答しようがないかと。
具体的なhtmlとそこから作成されるメニューを記載下さい
すみません、htmlを記載しました。
> htmlを記載しました。
h2もh3もないので、表示されるものはなにもないですけど?
h2やh3には最初からidが振られているのでしょうか?
それとも目次作成と並行してidを振る必要があるのでしょうか?
あと、当初付加していたh3クラスとかはやっぱり要らないということ?
すみません、色々な個所を修正しました。
目次作成と並行してidが必要です。そのidを元に、アンカーリンクを作成します。
h3のクラスは必要です。
再調整版アップしてあります
なにか動作がちがうなら指摘ください
回答1件
あなたの回答
tips
プレビュー