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

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

詳細はこちら
JavaScript

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

Q&A

解決済

1回答

1010閲覧

自動生成したリストのリンク先に見出しの親要素を指定したい

aaaaMAX

総合スコア16

JavaScript

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

0グッド

0クリップ

投稿2021/03/01 03:21

前提・実現したいこと

目次としてページ内リンクを自動生成したが、リンク先の指定に親要素のidを用いたい。
可能であればアドレスバーに#idを表示したくない。

また、初心者質問で恐縮ですが、こういったリストは閲覧者の環境に左右されないのでphpのほうがいいのでしょうか。

該当のソースコード

html

1<!DOCTYPE html> 2<html lang="ja"> 3 <head> 4 <meta charset="UTF-8"> 5 <title></title> 6 </head> 7 <body> 8 <div id="mokuji"> 9 <h1>目次</h1> 10 <div id="toc"></div> 11 </div> 12 13 <div id="01"><!-- ここにリンクしたい --> 14 <h2>01</h2><!-- リストの見出し --> 15 </div> 16 17 <div id="02"> 18 <h2>02</h2> 19 </div> 20 21 <div id="03"> 22 <h2>03</h2> 23 </div> 24 25 <div id="04"> 26 <h2>04</h2> 27 </div> 28 29 <div id="05"> 30 <h2>05</h2> 31 </div> 32 33 <script src="script.js"></script> 34 </body> 35</html> 36

js

1document.addEventListener('DOMContentLoaded', function () { 2 var target_toc_id = 'toc'; 3 var target_headline = 'h2'; 4 var toc_contents = document.getElementById( target_toc_id ); 5 var matches = document.querySelectorAll( target_headline ); 6 var ul = document.createElement('ul'); 7 matches.forEach( function (value, i) { 8 if ( value.id === '' ) { // if tag has no id, add id 9 value.id = i; 10 } 11 var li = document.createElement('li'); 12 var a = document.createElement('a'); 13 a.innerHTML = value.innerHTML; 14 a.href = '#' + value.id; 15 li.appendChild(a); 16 ul.appendChild(li); 17 }); 18 toc_contents.appendChild(ul); 19})

試したこと

parentNodeを使うのではないかと思ったが記述方法が分からなかった。
var oya = 'target_headline.parentNode';
と追加し、
a.href = '#' + value.id;

a.href = '#' + oya.id;
と書き替えたが、見出しのidを参照するままだった。

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

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

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

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

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

plasticgrammer

2021/03/01 04:58

target_headline を div にするのは都合が悪いのでしょうか?
aaaaMAX

2021/03/01 11:14

一番上の<div id="mokuji">をリスト一覧に入れたくないのと、リストの見出しがdiv内の全文になってしまうので都合が悪いです。
plasticgrammer

2021/03/02 00:15

divでループ(forEach)させて、その中で子要素のh2を参照すれば問題ないかと思いましたがいかがでしょうか。
aaaaMAX

2021/03/02 03:19

var target_h2 = 'h2'; var li = document.createElement('li'); var a = document.createElement('a'); a.innerHTML = target_h2.innerHTML; と書き替えたところ、リストが全て「undefined」になり、また、#mokujiもリストに組み込まれてしまいました。もし良ければ詳細なアドバイスをお願いいたします。
plasticgrammer

2021/03/02 04:23

divでループ(forEach)させた場合、 上記コードだと、forEachの【value】が1つ1つのdiv要素になるかと思います。 そのdiv要素の子となるh2を、value.querySelector("h2")で参照して、innerHTMLを取得する という流れでいけるのではと思いました。
aaaaMAX

2021/03/02 06:15

var li = document.createElement('li'); var a = document.createElement('a'); a.innerHTML = value.querySelector("h2").innerHTML; こういうことでいいでしょうか?試してみたのですが、リストが生成されなくなってしまいました。 念のため a.innerHTML = value.querySelector("h2");も試しましたが、この場合はリストは生成されたものの、リストの一番目が#mokujiへのリンクかつ見出しはなし、それ以降は見出しが[object HTMLHeadingElement]となりました。
plasticgrammer

2021/03/02 06:50

すみません。 単純にdivで抽出すると、id="mokuji"のdivまで対象となるせいですね。 一旦回答として記入しますので、そちらを参照ください。
guest

回答1

0

ベストアンサー

下記のようにするのはどうでしょうか。

html

1<!DOCTYPE html> 2<html lang="ja"> 3 <head> 4 <meta charset="UTF-8"> 5 <title></title> 6 </head> 7 <body> 8 <div id="mokuji"> 9 <h1>目次</h1> 10 <div id="toc"></div> 11 </div> 12 13 <div class="topic" id="01"><!-- ここにリンクしたい --> 14 <h2>01</h2><!-- リストの見出し --> 15 </div> 16 17 <div class="topic" id="02"> 18 <h2>02</h2> 19 </div> 20 21 <div class="topic" id="03"> 22 <h2>03</h2> 23 </div> 24 25 <div class="topic" id="04"> 26 <h2>04</h2> 27 </div> 28 29 <div class="topic" id="05"> 30 <h2>05</h2> 31 </div> 32 33 </body> 34</html>

js

1document.addEventListener('DOMContentLoaded', function () { 2 var target_toc_id = 'toc'; 3 var target_headline = '.topic'; 4 var toc_contents = document.getElementById( target_toc_id ); 5 var matches = document.querySelectorAll( target_headline ); 6 var ul = document.createElement('ul'); 7 matches.forEach( function (value, i) { 8 if ( value.id === '' ) { // if tag has no id, add id 9 value.id = i; 10 } 11 var li = document.createElement('li'); 12 var a = document.createElement('a'); 13 a.innerHTML = value.querySelector('h2').innerHTML; 14 a.href = '#' + value.id; 15 li.appendChild(a); 16 ul.appendChild(li); 17 }); 18 toc_contents.appendChild(ul); 19})

投稿2021/03/02 06:55

plasticgrammer

総合スコア629

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

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

aaaaMAX

2021/03/02 07:11

ご回答のとおりにしたところ、無事リストが生成されました。 自分でもいじってみたところ、一番最初のdiv内にh2がなかったためにリストが生成できなくなったようですね。 最後までお付き合いいただきありがとうございました。 URLのほうは自分でももう少し試してみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問