🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

1回答

923閲覧

JavaScriptで、<li>を目的の場所に追加する方法

vankick

総合スコア22

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2019/10/09 00:50

編集2019/10/09 02:59

現在、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>の後に追加することができるでしょうか。どなたかお力をお貸しいただきたいです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

miyabi_takatsuk

2019/10/09 01:10 編集

まず、理想形にあります、クラスに要素名はそもそもエラーの元になるのでやめましょう。 また、JavaScript処理を適用させようとしている元のHTMLも記載下さい。 でないと回答しようがないかと。
yambejp

2019/10/09 01:16

具体的なhtmlとそこから作成されるメニューを記載下さい
vankick

2019/10/09 02:44

すみません、htmlを記載しました。
yambejp

2019/10/09 02:46

> htmlを記載しました。 h2もh3もないので、表示されるものはなにもないですけど?
yambejp

2019/10/09 02:58 編集

h2やh3には最初からidが振られているのでしょうか? それとも目次作成と並行してidを振る必要があるのでしょうか? あと、当初付加していたh3クラスとかはやっぱり要らないということ?
vankick

2019/10/09 03:01

すみません、色々な個所を修正しました。 目次作成と並行してidが必要です。そのidを元に、アンカーリンクを作成します。 h3のクラスは必要です。
yambejp

2019/10/09 03:03

再調整版アップしてあります なにか動作がちがうなら指摘ください
guest

回答1

0

ベストアンサー

ざっくり

javascript

1<script> 2window.addEventListener('DOMContentLoaded', ()=>{ 3 var menu=document.querySelector('#menu'); 4 [].forEach.call(document.querySelectorAll('h2,h3'),x=>{ 5 var li=document.createElement('li'); 6 menu.appendChild(li); 7 var a=document.createElement('a'); 8 a.setAttribute('href','#'); 9 a.textContent=x.textContent; 10 li.appendChild(a) 11 switch(x.nodeName){ 12 case "H2": 13 /* h2特有の処理がないので空 */ 14 break; 15 case "H3": 16 li.classList.add('h3'); 17 break; 18 } 19 }); 20}); 21</script> 22<ul id="menu"></ul> 23<h2>h-1</h2> 24test 25<h3>h-1-1</h3> 26test 27<h3>h-1-2</h3> 28test 29<h2>h-2</h2> 30test 31<h3>h-2-1</h3> 32test 33<h3>h-2-2</h3> 34test 35<h3>h-2-2</h3> 36test 37<h2>h-3</h2>

再調整版

javascript

1<style> 2.h3{background-Color:yellow} 3</style> 4<script> 5window.addEventListener('DOMContentLoaded', ()=>{ 6 var menu=document.querySelector('#index'); 7 var ul=document.createElement('ul'); 8 menu.appendChild(ul); 9 [].forEach.call(document.querySelectorAll('h2,h3'),(x,y)=>{ 10 var id='target-'+(y+1).toString(); 11 x.setAttribute('id',id); 12 var li=document.createElement('li'); 13 ul.appendChild(li); 14 var a=document.createElement('a'); 15 a.setAttribute('href','#'+id); 16 a.textContent=x.textContent; 17 li.appendChild(a) 18 switch(x.nodeName){ 19 case "H2": 20 /* h2特有の処理がないので空 */ 21 break; 22 case "H3": 23 li.classList.add('h3'); 24 break; 25 } 26 }); 27}); 28</script> 29<div id="index"> 30 <p class="toc-title">目次</p> 31 <!-- ここに目次が<ul><li></li></ul>の形で表示される --> 32</div> 33<h2>h-1</h2> 34test 35<h3>h-1-1</h3> 36test 37<h3>h-1-2</h3> 38test 39<h2>h-2</h2> 40test 41<h3>h-2-1</h3> 42test 43<h3>h-2-2</h3> 44test 45<h3>h-2-2</h3> 46test 47<h2>h-3</h2> 48<!-- 頭出しするためダミーのbr --> 49<br><br><br><br><br><br><br><br><br><br><br> 50<br><br><br><br><br><br><br><br><br><br><br> 51<br><br><br><br><br><br><br><br><br><br><br> 52<br><br><br><br><br><br><br><br><br><br><br> 53

投稿2019/10/09 01:30

編集2019/10/09 02:58
yambejp

総合スコア116694

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

vankick

2019/10/09 03:07

わざわざhtmlの作成のお手間を取らせてしまってすみませんでした! 当初希望していた動きになりました。ありがとうございます! forEach.callやswitch処理など、自分では全く思いつかない書き方なので非常に勉強になります。 ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問