質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.48%
JavaScript

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

Q&A

解決済

4回答

1252閲覧

複数ある画像のモーダルの実装 シンプルな書き方

Karasimentaiko

総合スコア5

JavaScript

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

0グッド

0クリップ

投稿2019/12/26 07:42

編集2019/12/26 08:09

前提・実現したいこと

JAVASCRIPT によるモダールの実装

アウトプットの一貫でJAVASCRIPTのモーダルの実装を行なっております。
それぞれの写真を押したらそれぞれのモーダルが表示されるということを
やってみたかったのですが、各写真と各モーダルに固有のクラスを付与して、
クリックしたら表示されるようになったのですが、 
各写真にクラスをつけ、JavaScriptにその数だけコードを書くのは
今後写真などが増えたりした場合、運用やメンテナンス的にあまりよくないと
思い質問させていただきました。
色々ネットや本で調べてみたのですが、結局できずに最終的に
2つ目のコードで詰まってしまいました。これだとクリックしたら表示はされますが、
他のmodalを持ったクラスの写真も表示されて閉じます。

自分がやりたかったのは、その写真を押したらその写真のモーダルだけが表示され
もう一度押したら閉じる機能を持ったモーダルです。

根本的に考えた方が違うと思うのですが、自分で考えてダメでしたので
質問させていただきました。
よろしくお願いします。

HTML <figure class="modal modal-1"> <img src="img/sample/data-1.jpg" alt="写真その1" class="modal__img"> <figcaption>sample</figcaption> </figure> <div class="popup popup-1"> <figure> <img src="img/sample/data-1__large.jpg" alt="写真その1" class="popup__img"> <figcaption class="popup__caption">sample</figcaption> </figure> </div> <figure class="modal modal-2"> <img src="img/sample/data-2.jpg" alt="写真その2" class="modal__img"> <figcaption>sample</figcaption> </figure> <div class="popup popup-2"> <figure> <img src="img/sample/data-2__large.jpg" alt="写真その2" class="popup__img"> <figcaption class="popup__caption">sample</figcaption> </figure> </div> <figure class="modal modal-3"> <img src="img/sample/data-3.jpg" alt="写真その3" class="modal__img"> <figcaption>sample</figcaption> </figure> <div class="popup popup-3"> <figure> <img src="img/sample/data-3__large.jpg" alt="写真その3" class="popup__img"> <figcaption class="popup__caption">sample</figcaption> </figure> </div> function modalNav(){ const popup = document.querySelector('.popup'); let modal1 = document.querySelector('.modal-1'); let popup1 = document.querySelector('.popup-1'); let modal2 = document.querySelector('.modal-2'); let popup2 = document.querySelector('.popup-2'); let modal3 = document.querySelector('.modal-3'); let popup3 = document.querySelector('.popup-3'); modal1.addEventListener('click',()=>{ popup1.classList.add('active'); }); popup1.addEventListener('click',()=>{ popup1.classList.remove('active'); }); modal2.addEventListener('click',()=>{ popup2.classList.toggle('active'); }); popup2.addEventListener('click',()=>{ popup2.classList.remove('active'); }); modal3.addEventListener('click',()=>{ popup3.classList.toggle('active'); }); popup3.addEventListener('click',()=>{ popup3.classList.remove('active'); }); } modalNav();

2つ目

document.querySelectorAll('.modal').forEach((modalTarget)=>{ modalTarget.addEventListener('click',()=>{ const popup = document.querySelectorAll('.popup'); popup.forEach((popupTarget)=>{ popupTarget.classList.add('active'); popupTarget.addEventListener('click',()=>{ popupTarget.classList.remove('active'); }); }); }); });

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

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

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

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

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

guest

回答4

0

  • 相対位置をとるとか
  • 同じインデックスで処理をするとか
  • カスタムデータで紐付けするとか

いろいろあります

投稿2019/12/26 08:30

yambejp

総合スコア114767

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

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

yambejp

2019/12/26 08:31

<script> window.addEventListener('DOMContentLoaded',()=>{ document.addEventListener('click',e=>{ if(!e.target.closest('dialog')){ var n=document.querySelector('dialog[open]'); if(n) n.removeAttribute("open"); } }); document.querySelectorAll('.modal').forEach(modalTarget=>{ modalTarget.addEventListener('click',e=>{ e.stopPropagation(); var n=document.querySelector('dialog[open]'); if(n) n.removeAttribute("open"); const popup=modalTarget.nextElementSibling; popup.setAttribute("open","open"); }); }); }); </script> <div class="modal">m1</div> <dialog class="popup">p1</dialog> <div class="modal">m2</div> <dialog class="popup">p2</dialog> <div class="modal">m3</div> <dialog class="popup">p3</dialog>
Karasimentaiko

2019/12/26 08:59

ありがとうございます。早速試してみます。
guest

0

各写真にクラスをつけ、JavaScriptにその数だけコードを書くのは

今後写真などが増えたりした場合、運用やメンテナンス的にあまりよくないと
思い質問させていただきました。

サーバ側で動的にHTML生成していれば、クラスを付けることに、抵抗も無いだろうと感じましたので、
スタティックなHTML+CSS+JavaScript での方法論になります。

document.querySelector(), document.querySelectorAll() の引数に 属性セレクタ を与えるのはどうでしょうか。


スタティックなサイトを管理するときには、画像などのサブリソースは、フォルダを決めているはずです。
そうであれば、img[src*="img/sample/"] のように画像のURLを評価するセレクタを利用できます。

MDN では記されていませんが、img[src^="img/sample/"][src$=".jpg"] のように、
ブラケットを連続させることで複数の属性セレクタを指定できます。

このように取得した要素から、直近の祖先を探す closest()も活用すると、イベントリスナのハンドリング対象を自動化できると思います。

追記)
classListの toggle() も試してみてください。

投稿2019/12/26 08:13

編集2019/12/26 08:21
AkitoshiManabe

総合スコア5432

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

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

Karasimentaiko

2019/12/26 09:01

ありがとうございます。早速試してみます。
guest

0

まともな回答は出ていると思うので

CSS

1details[open] { 2 position: fixed; 3 top: 0; 4 right: 0; 5 bottom: 0; 6 left: 0; 7 background: #999; 8} 9 10details[open] summary { 11 display: none; 12}

JavaScript

1document.body.addEventListener('click', (event) => { 2 const target = event.target; 3 if (target.closest('summary')) { 4 return true; 5 } 6 7 const details = target.closest('details'); 8 if (details) { 9 details.open = !details.open; 10 } 11});

投稿2019/12/26 09:34

x_x

総合スコア13749

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

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

x_x

2019/12/27 01:19

よく考えたらこれ CSS だけでもできそうなので試してみてください。
guest

0

ベストアンサー

こういうものを作る時は、
トリガーとターゲットに分類し、
それぞれに、トリガーとターゲット両方に、共通のクラスを付与し、
ターゲット一個一個には、それぞれのIDを付与します。
つまりフォーマットは同じだけど、一個一個は別物、という状態を作ります。
対して、トリガーにも同じ共通のクラスをつけるのですが、
IDを振ったり、data属性を使い、特定のターゲットだけを指定できるようにします。

html

1<!-- 共通のボタン仕様として、modalクラスを付与する --> 2<!-- 表示させたい対象のIDをdata-targetに与える --> 3<figure class="modal" data-target="popup1"> 4 <img src="img/sample/data-1.jpg" alt="写真その1" class="modal__img"> 5 <figcaption>sample</figcaption> 6</figure> 7 8<figure class="modal" data-target="popup2"> 9 <img src="img/sample/data-2.jpg" alt="写真その2" class="modal__img"> 10 <figcaption>sample</figcaption> 11</figure> 12<!-- ...以下いくらでもボタンを追加 --> 13 14 15<!-- 共通のモーダルウィンドウの仕様として、popupクラスを付与する --> 16<!-- 個々の一意の固有情報として、IDを付与 --> 17<div class="popup" id="popup1"> 18 <figure> 19 <img src="img/sample/data-1__large.jpg" alt="写真その1" class="popup__img"> 20 <figcaption class="popup__caption">sample</figcaption> 21 </figure> 22</div> 23 24<div class="popup" id="popup2"> 25 <figure> 26 <img src="img/sample/data-2__large.jpg" alt="写真その2" class="popup__img"> 27 <figcaption class="popup__caption">sample</figcaption> 28 </figure> 29</div> 30<!-- ...以下いくらでもモーダルを追加 -->

javascript

1document.querySelectorAll('.modal').forEach(modalTarget => { 2 modalTarget.addEventListener('click', e => { 3 // クリックした要素から、data-targetを取得 4 const targetId = e.target.dataset.target; 5 // 対象のモーダルにactiveクラスを付与 6 document.getElementById(targetId).classList.add('active'); 7 }); 8}); 9 10// モーダル本体には、別でイベントを付与したほうがいい 11document.querySelectorAll('.popup').forEach(popupTarget => { 12 popupTarget.addEventListener('click', e => { 13 e.target.classList.remove('active'); 14 }); 15});

とはいっても、他にも方法はいっぱいあるので、もっともっと研究されるといいですよ。

投稿2019/12/26 08:27

miyabi_takatsuk

総合スコア9528

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

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

Karasimentaiko

2019/12/26 09:03

ありがとうございます。モーダル本体に別でイベントを付与する考え方などとても参考になります。 早速試して理解を深めていきます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問