前提
JavaScriptでモーダルウィンドウを実装したいと考えています。
実現したいこと
HTML上のclass名は同一の、モーダルウィンドウを複数用意し、
個別にクリックイベントの処理を行いたいです。
class名を個別につけて、その都度JSを書いて実装することはできるのですが、
同じソースコードの羅列になり後から見にくいので
まとめてしまいたいです。
発生している問題・エラーメッセージ
3つのモーダルウィンドウを用意して試したところ、
現在のコードではクリックした際、3つすべての要素を取得してしまい
すべてが重なって表示されてしまいます。
(結果最後の要素で指定した画像が最上面となり表示されます)
該当のソースコード
HTML
1 <body> 2 <div class="second-area"> 3 <!-- 1つめ --> 4 <div class="modalOpen other-img"> 5 <img src="image/column1.jpg"> 6 </div> 7 <!-- 1つめのモーダルウィンドウ --> 8 <div class="easyModal modal"> 9 <div class="modalScale modal-scale"> 10 <div class="modal-content"> 11 <div class="modal-header"> 12 <span class="modalClose toggle"></span> 13 </div> 14 <div class="modal-body"> 15 <img src="image/column1.jpg"> 16 </div> 17 <p>Lorem ipsum dolor sit amet.</p> 18 </div> 19 </div> 20 </div> 21 <!-- 2つめ --> 22 <div class="modalOpen other-img"> 23 <img src="image/column2.jpg"> 24 </div> 25 <!-- 2つめのモーダルウィンドウ --> 26 <div class="easyModal modal"> 27 <div class="modalScale modal-scale"> 28 <div class="modal-content"> 29 <div class="modal-header"> 30 <span class="modalClose toggle"></span> 31 </div> 32 <div class="modal-body"> 33 <img src="image/column2.jpg"> 34 </div> 35 <p>Lorem ipsum dolor sit amet.</p> 36 </div> 37 </div> 38 </div> 39 <!-- 3つめ --> 40 <div class="modalOpen other-img"> 41 <img src="image/column3.jpg"> 42 </div> 43 <!-- 3つめのモーダルウィンドウ --> 44 <div class="easyModal modal"> 45 <div class="modalScale modal-scale"> 46 <div class="modal-content"> 47 <div class="modal-header"> 48 <span class="modalClose toggle"></span> 49 </div> 50 <div class="modal-body"> 51 <img src="image/column3.jpg"> 52 </div> 53 <p>Lorem ipsum dolor sit amet.</p> 54 </div> 55 </div> 56 </div> 57 </div> 58</body>
SCSS
1@charset "utf-8"; 2// 共通スタイル 3* { 4 margin: 0; 5 padding: 0; 6 -webkit-box-sizing: border-box; 7 box-sizing: border-box; 8 &::before, 9 &::after { 10 -webkit-box-sizing: border-box; 11 box-sizing: border-box; 12 } 13} 14html { 15 font-size: 62.5%; 16 overflow: auto; 17} 18img { 19 max-width: 100%; 20} 21body { 22 overflow: hidden; 23 width: 100%; 24 height: 100vh; 25 display: flex; 26 justify-content: center; 27 align-items: center; 28} 29 30 31// スタイル 32.second-area { 33 width: 80%; 34 display: flex; 35 gap: 20px; 36 .other-img { 37 flex-grow: 1; 38 cursor: pointer; 39 } 40 .easyModal { 41 display: none; 42 } 43 .modal { 44 z-index: 20; 45 width: 100vw; 46 height: 100vh; 47 position: fixed; 48 top: 0; 49 left: 0; 50 overflow: auto; 51 .modal-scale { 52 width: 100%; 53 height: 100%; 54 background: rgba(0, 0, 0, 0.6); 55 display: flex; 56 justify-content: center; 57 align-items: center; 58 .modal-content { 59 background: #f4f4f4; 60 width: 40vw; 61 height: 40vw; 62 display: flex; 63 justify-content: center; 64 align-items: center; 65 flex-direction: column; 66 gap: 10px; 67 position: relative; 68 box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.2), 69 5px 5px 10px rgba(0, 0, 0, 0.17); 70 animation-name: modalopen; 71 animation-duration: 1s; 72 @keyframes modalopen { 73 from { 74 opacity: 0; 75 } 76 to { 77 opacity: 1; 78 } 79 } 80 .modal-header { 81 position: absolute; 82 top: 10px; right: 10px; 83 cursor: pointer; 84 .toggle { 85 display: block; 86 position: relative; 87 width: 30px; 88 height: 30px; 89 border: 2px solid #333; 90 border-radius: 50%; 91 background: #fff; 92 &::before, 93 &::after { 94 content: ""; 95 position: absolute; 96 top: 50%; 97 left: 50%; 98 width: 3px; 99 height: 22px; 100 background: #333; 101 } 102 &::before { 103 transform: translate(-50%, -50%) rotate(45deg); 104 } 105 &::after { 106 transform: translate(-50%, -50%) rotate(-45deg); 107 } 108 } 109 } 110 .modal-body { 111 width: 80%; 112 img { 113 border-radius: 4px; 114 } 115 } 116 p { 117 font-size: 1.5rem; 118 letter-spacing: 2px; 119 } 120 } 121 } 122 } 123}
JavaScript
1window.addEventListener('DOMContentLoaded', function() { 2 3 window.onload = function() { 4 5 let buttonOpen = document.querySelectorAll('.modalOpen'); 6 let modal = document.querySelectorAll('.easyModal'); 7 let buttonClose = document.querySelectorAll('.modalClose'); 8 let modalScale = document.querySelectorAll('.modalScale'); 9 10 // ボタンがクリックされた時 11 buttonOpen.forEach(x => { 12 x.addEventListener('click', modalOpen); 13 function modalOpen() { 14 modal.forEach(y => { 15 y.style.display = "block"; 16 }); 17 } 18 }); 19 20 // トグルがクリックされた時 21 buttonClose.forEach(x => { 22 x.addEventListener('click', modalClose); 23 function modalClose() { 24 modal.forEach(y => { 25 y.style.display = "none"; 26 }); 27 } 28 }); 29 30 // モーダルコンテンツ以外がクリックされた時 31 modalScale.forEach(x => { 32 x.addEventListener('click', outsideClose); 33 function outsideClose(e) { 34 modalScale.forEach(y => { 35 if(e.target == y) { 36 modal.forEach(z => { 37 z.style.display = "none"; 38 }); 39 } 40 }); 41 } 42 }); 43 } 44});
試したこと
for文での記述も試したのですが、上記のコードと
同じ結果になってしまいました。
JavaScript
1window.addEventListener('DOMContentLoaded', function() { 2 3 // ボタンがクリックされた時 4 for( let i=0; i<buttonOpen.length; i++ ) { 5 buttonOpen[i].addEventListener('click', modalOpen); 6 function modalOpen() { 7 for( let i=0; i<modal.length; i++ ) { 8 modal[i].style.display = "block"; 9 } 10 } 11 } 12 13 // トグルがクリックされた時 14 for( let i=0; i<buttonClose.length; i++ ) { 15 buttonClose[i].addEventListener('click', modalClose); 16 function modalClose() { 17 for( let i=0; i<modal.length; i++ ) { 18 modal[i].style.display = "none"; 19 } 20 } 21 } 22 23 // モーダルコンテンツ以外がクリックされた時 24 for( let i=0; i<modalScale.length; i++ ) { 25 modalScale[i].addEventListener('click', outsideClose); 26 function outsideClose(event) { 27 if(event.target == modalScale[i]) { 28 for( let i=0; i<modal.length; i++ ) { 29 modal[i].style.display = "none"; 30 } 31 } 32 } 33 } 34 35});
何卒宜しくお願い致します。
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2022/07/15 07:55