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

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

詳細はこちら
JavaScript

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

Q&A

解決済

1回答

1051閲覧

スムーススクロールが一部条件下で機能しない

aaaaMAX

総合スコア16

JavaScript

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

0グッド

0クリップ

投稿2021/03/02 15:32

編集2021/03/03 12:48

前提・実現したいこと

作製したスムーススクロールが一部の条件下で動きません。
1.メニューがないページ
2.<a href="#"><div id="page_top"></div></a>
3.自動生成したメニューが参照しているh2.innerHTMLにhtmlタグが含まれている場合

1について、メニュー位置は画面サイズ次第で1~数行に変化するため、document.getElementById("menu").clientHeightを数字で代用することはできません。

1~3の条件でも同一のJavaScriptを適用したいのですが、どのようにすればいいでしょうか。それとも不可能でしょうか。

該当のソースコード

html

1<!DOCTYPE html> 2<html lang="ja"> 3 <head> 4 <meta charset="UTF-8"> 5 <link rel="stylesheet" href="style.css" type="text/css" /> 6 <title></title> 7 </head> 8 <body> 9 <div id="menu"><!-- 1の例(ここを消すと動かない) --> 10 </div> 11 12 <div class="topic" id="x01"> 13 <h2>01</h2> 14 <a href="#x02">02</a> 15 </div> 16 17 <div class="topic" id="x02"><!-- 3の例 --> 18 <h2><strong>02</strong></h2> 19 <a href="#">top</a> 20 </div> 21 22 <div class="topic" id="x03"> 23 <h2>03</h2> 24 <a href="#">top</a> 25 </div> 26 27 <a href="#"><div id="page_top"></div></a><!-- 2の例 --> 28 <script src="script.js"></script> 29</body> 30</html>

css

1@charset "utf-8"; 2#menu { 3 display: block; 4 margin: 0; 5 position:fixed; 6 top: 0; 7 width: 100%; 8 background: red; 9} 10 11div { 12 margin-top: 150px; 13} 14 15.topic{height:999px} 16 17#page_top { 18 display: block; 19 position:fixed; 20 bottom: 50px; 21 right: 50px; 22 background:red; 23 width: 50px; 24 height: 50px; 25 z-index: 999; 26}

js

1//スムーズスクロール 2document.addEventListener('click',e=>{ 3 if([...document.querySelectorAll('[href^="#"]')].includes(e.target)){ 4 const href=e.target.getAttribute("href"); 5 const top=(href=="#" || document.querySelector(href)==null)?0:(window.scrollY+document.querySelector(href).getBoundingClientRect().top-document.getElementById("menu").clientHeight); 6 e.preventDefault(); 7 window.scroll({ 8 top, 9 behavior: "smooth", 10 }); 11 } 12}); 13 14//メニュー生成 15document.addEventListener('DOMContentLoaded', function () { 16 const nav_toc_id = 'menu'; 17 const nav_headline = '.topic'; 18 const nav_contents = document.getElementById(nav_toc_id); 19 const nav_matches = document.querySelectorAll(nav_headline); 20 const ul = document.createElement('ul'); 21 nav_matches.forEach( function (value, i) { 22 if ( value.id === '' ) { // if tag has no id, add id 23 value.id = i; 24 } 25 const li = document.createElement('li'); 26 const a = document.createElement('a'); 27 a.innerHTML = value.querySelector('h2').innerHTML; 28 a.href = '#' + value.id; 29 li.appendChild(a); 30 ul.appendChild(li); 31 }); 32 nav_contents.appendChild(ul); 33}) 34

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

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

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

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

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

guest

回答1

0

ベストアンサー

アンカーの中にHTML要素が入る可能性があるのですね?

であれば

javascript

1e.target 2↓↓↓ 3e.target.closest('a')

※2箇所変更してください

投稿2021/03/03 00:41

yambejp

総合スコア116694

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

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

aaaaMAX

2021/03/03 04:40

innnerHTMLが問題ではなかったのですね。教えていただいたとおりにしたところ、2と3の場合については解決しました。 1の場合についてはやはり別途jsを用意したほうがいいのでしょうか?
yambejp

2021/03/03 04:48

メニューがどういう機能なのかいまいち理解できていません 具体的になにをどうする想定なのでしょうか?
aaaaMAX

2021/03/03 05:02

私は一つのサイト上で複数の似ているが異なる情報を公開しています。例えば猫の飼い方、犬の飼い方…というようにいくつかのまとまりに分けています。 最初のページでは<div class="topic">ごとに動物の種類を分けており、ユーザビリティ向上のためにメニューを用意しています。 さらに猫の飼い方のページは<div class="topic">ごとに購入方法、普段の接し方…などに大別した目次になっており、これらの項目は今後増えたり入れ替えたりする可能性があるので私の利便性向上のためにリスト生成をすることにしました。 そして、細分化された目次から飛んだ先のページは一つの情報しか載っておらず、メニューがあっても邪魔なだけなのでつけていません。
yambejp

2021/03/03 05:43

メニューがないと動かないというのがよくわかりません
aaaaMAX

2021/03/03 05:59

スムーススクロールにdocument.getElementById("menu").clientHeightを加え (window.scrollY+document.querySelector(href).getBoundingClientRect().top-document.getElementById("menu").clientHeight); としているので、メニューがないとスムーススクロールが機能しなくなります
aaaaMAX

2021/03/03 06:20

メニューがない場合でも<a href="#">top</a>では機能するのですが<a href="#x02">02</a>では機能しません
aaaaMAX

2021/03/06 05:04

2,3については解決したので、この質問については締めさせていただきます。1については私の質問の仕方が良くなかったと思うので再度別投稿しようと思います。回答から察するにe.target.closest('a')にすることでa以外のタグの影響を無視できるようになるようですね。勉強になりました。前回に引き続きありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問