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

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

詳細はこちら
CSS3

CSS(Cascading Style Sheet)の第3版です。CSS3と略されることが多いです。色やデザインを柔軟に変更することが可能になります。

HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

JavaScript

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

Q&A

解決済

2回答

1241閲覧

addEventListenerのクリックイベントでディスプレイの表示・非表示の切り替えをしたい

Naoki_Pro

総合スコア23

CSS3

CSS(Cascading Style Sheet)の第3版です。CSS3と略されることが多いです。色やデザインを柔軟に変更することが可能になります。

HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

JavaScript

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

0グッド

0クリップ

投稿2019/09/23 05:56

編集2019/09/23 06:59

前提・実現したいこと

現在、webページの模写をしています。
addEventListenerのクリックイベントでディスプレイを表示させ、その表示させたディスプレイ以外の場所(bodyタグ)をクリックするとディスプレイが消えるようにしたいです。

*上記のディスプレイとは<div class="guide"><div class="guide-2">のことです

htmlは見やすいように、表示・非表示の切り替えをしたいディスプレイとクリックする場所以外は省略してあります。

発生している問題・エラーメッセージ

エラーメッセージは出ませんが、ディスプレイ自体を表示することがそもそもできません。

該当のソースコード

html

1<body> 2<header> 3<div class="hd-link" id="hd-margin"> 4 <p>ホストをはじめる</p> 5 </div> 6</header> 7<main> 8<div class="guide close"> 9 <div class="sur"> 10 <h4>宿泊先</h4> 11 <p>お部屋を掲載</p> 12 <h2>横浜市でホスティング、月最大¥101,538の収入に。</h2> 13 <p>お家のホスティングについて</p> 14 </div> 15 </div> 16<div class="guide-2 close"> 17 <div class="sur"> 18 <h4>体験</h4> 19 <p>体験をホストする</p> 20 <h2>好きなことを世界とシェアして、収入を得よう</h2> 21 </div> 22 </div> 23</main> 24<footer> 25</footer> 26</body>

css

1.sur { 2 width: 230px; 3 margin: 0 auto; 4 background: rgb(255, 255, 255); 5} 6.guide { 7 height: 140px; 8 width: 300px; 9 margin: 0 auto; 10 background: rgb(255, 255, 255); 11 position: absolute; 12 right: 300px; 13 border: 1px solid rgb(180, 180, 180); 14 box-sizing: border-box; 15 border-bottom: none; 16} 17.guide-2 { 18 width: 300px; 19 margin: 0 auto; 20 background: rgb(255, 255, 255); 21 position: absolute; 22 right: 300px; 23 top: 220px; 24 border: 1px solid rgb(180, 180, 180); 25 box-sizing: border-box; 26} 27.close { 28 display: none; 29}

JavaScript

1let guide = document.getElementsByClassName("guide")[0]; 2let guide2 = document.getElementsByClassName("guide-2")[0]; 3let nav = document.getElementById("hd-margin"); 4let body =document.getElementsByTagName("body")[0]; 5 6let nav2 = function() { 7 nav.addEventListener("click", function() { 8 guide.classList.remove("close"); 9 guide2.classList.remove("close"); 10 body.addEventListener("click", function() { 11 guide.classList.add("close"); 12 guide2.classList.add("close"); 13 nav2(); 14 }); 15 }); 16}; 17 18nav2();

試したこと

試しに全く同じ場所をクリックして、ディスプレイの表示・非表示の切り替えができるか試したら、それは実装可能でした。
その際はJavaScriptのbody.addEventListenerの箇所をnav.addEventListenerに切り替えました。

またこの問題を解決したとしても次は、表示させたディスプレイ以外のbodyタグ内をクリックした時のみ、ディスプレイを非表示にしたいという問題が出てくると思いますが、そこに関しての解決法は全く分かりません。

補足情報(FW/ツールのバージョンなど)

Atomエディタ version 1.40.1

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

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

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

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

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

kei344

2019/09/23 06:46

「ディスプレイを表示させ」とありますが、「ディスプレイ」とは具体的にどこを指しているのかが提示されていません。
Naoki_Pro

2019/09/23 07:00

分かりにくくてすみません。質問を修正いたしました。
guest

回答2

0

ベストアンサー

まずは、addEventListener は既にあるイベントを上書きせずに追加していくので、クリックイベント内にaddEventListenerを記述すると、クリックするたびにイベントリステナーが追加されてしまうので、おかしな動作になります。

ドキュメント全体で、特定の要素をクリックしたか、それ以外の要素をクリックしたかを判定するには、下記のようにdocument.addEventListenerのイベントで場合分けしたらどうでしょうか。

js

1document.addEventListener('click', function(e){ 2 let guide = e.target.closest(".guide"); 3 let guide2 = e.target.closest(".guide-2"); 4 5 if(guide){ 6 console.log("guideをクリック"); 7 } else if(guide2) { 8 console.log("guide-2をクリック"); 9 }else { 10 console.log("guide, guide-2以外をクリック"); 11 };; 12}, false);

投稿2019/09/23 08:34

hatena19

総合スコア34073

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

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

siruku6

2019/09/23 08:41 編集

重なり合う要素をクリックした場合に、どちらの要素がクリックされたのかを特定する方法があるのは知りませんでした。 大変勉強になります。
Naoki_Pro

2019/09/27 01:58

回答して頂きありがとうございます。 返信が遅くなってしまいすみません。 hatena19さんの方法を試したら、上手く稼働させることができました。 ありがとうございます。
guest

0

2点注意を

nav2()メソッドが再帰呼出しされている

javascript

1let nav2 = function() { 2 nav.addEventListener("click", function() { 3 guide.classList.remove("close"); 4 guide2.classList.remove("close"); 5 body.addEventListener("click", function() { 6 guide.classList.add("close"); 7 guide2.classList.add("close"); 8 nav2(); // ←nav2の中でnav2が呼び出されている 9 }); 10 }); 11};

何か特別な理由がない限りこういうことはやめた方がいいです。
処理が複雑になり過ぎます。
計算処理ならまだしも、domの操作で再起を使うくらいなら、代替手段を考えましょう。

navがbody内に含まれている

navをクリックしたとき、bodyもクリックしたことになっているので、'close'クラスが削除(remove)された瞬間に再度追加(add)される結果となっているように見えます。

そのため、結果として見た目に変更は生じません。

Na_Yさんのおっしゃる「ディスプレイ」を消す手段は、bodyをクリックしたときではなく、navを含まない何か別の要素をクリックしたときにする必要があるように思います。

投稿2019/09/23 08:13

siruku6

総合スコア1382

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

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

Naoki_Pro

2019/09/27 01:59

返信が遅くなってしまいすみません。 アドバイスして頂きありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問