
実現したいこと
モーダルを閉じたときに上に戻らないようにする。
前提
ページ内に複数設置できるモーダルをJavascriptで作っています。
モーダル開いているときも背景を固定したいです。
発生している問題・エラーメッセージ
1回目は、モーダル開く・閉じても背景固定しくれていますが、
2回目の開くまでは背景固定していて、閉じると上へスクロールされてしまいます。
3回目も開くまでは背景固定、閉じると上へ戻ります。
試したこと
「 window.pageYOffset 」が原因のような気がしますが、どうしたらよいのか分かりません。
よろしくお願い致します(o_ _)o
修正
cssが間違っていたので修正。
javascriptも意図した挙動になるように修正。
cssのクラスを修正した後html側も修正
▼修正後
HTML
1<p><a class="js_mdl_open mdl_open_txt" href="" data-mdlopen="mdl1">モーダル開く</a></p> 2 3<div class="mdl js_mdl" data-mdl="mdl1"><!-- モーダル --> 4 <div class="js_mdl_overlay mdl_overlay"></div> 5 <div class="mdl_wrapper"> 6 <div class="mdl_white"><!-- white --> 7 <div class="mdl_content"><!-- content --> 8 <div class="mdl_close"><span class="mdl_close_icon js_mdl_close_icon"></span></div><!-- 閉じるボタン --> 9 <div class="mdl_main"><!-- main --> 10 <div class="mdl_main_content"> 11 <p>text等が入る</p> 12 </div> 13 </div><!--END main --> 14 </div><!--END content --> 15 16 </div><!--END white --> 17 </div><!--END mdl_wrapper --> 18 </div><!--END mdl -->
▼修正後
CSS
1.mdl { 2 display: none; 3 opacity:0; 4} 5.mdl.mdl_active { 6 display: block; 7 opacity:1; 8 animation-name: mdlactive; 9 animation-duration: .3s; 10 width: 100%; 11 height: 100vh; 12 position: fixed; 13 top: 0; 14 left: 0; 15 background-color: transparent; 16 overscroll-behavior: contain; 17 overflow-y: scroll; 18 z-index: 10000; 19} 20@keyframes modalactive{ 21 from {opacity:0;} 22 to {opacity: 1;} 23} 24.mdl_overlay { 25 position:fixed; 26 top:0; 27 left:0; 28 z-index: 10000; 29 width: 100%; 30 height: 100%; 31 background-color: #000; 32 opacity: 0.7; 33} 34.mdl_wrapper { 35 position:fixed; 36 top:0; 37 left:0; 38 z-index: 10001; 39 width: 100%; 40 height: 100%; 41 padding: 20px; 42 display: flex; 43 justify-content: center; 44 align-items: center; 45} 46.mdl_white { 47 width: min(100%,770px); 48 height: auto; 49 background-color: #fff; 50z-index: 10002; 51} 52.mdl_content { 53 background-color: #fff; 54 width: 100%; 55 height: 100%; 56 max-height: 600px; 57 overflow-y: scroll; 58 overflow-x: hidden; 59 position: relative;/* 閉じるアイコン */ 60} 61.mdl_main { 62 padding: 2em 1.5em; 63} 64.mdl_main_content { width: 100%;} 65/* 閉じるアイコン */ 66.mdl_close { 67 position: absolute; 68 top: 0; 69 right: 0px; 70} 71.mdl_close_icon { 72 display: block; 73 width: 20px; 74 height: 20px; 75 border-radius: 50%; 76 transform: rotate( 45deg); 77 padding-left: 25px; 78 padding-right: 25px; 79 padding-top: 10px; 80 padding-bottom: 40px; 81 margin-top: 10px; 82} 83.mdl_close_icon::before { 84 content: ""; 85 display: block; 86 width: 31px; 87 height: 1px; 88 background-color: #222; 89 transform: translate(-15px,15px); 90} 91.mdl_close_icon::after { 92 content: ""; 93 display: block; 94 width: 1px; 95 height: 31px; 96 background-color: #222; 97} 98.mdl_close_icon:hover { 99 cursor: pointer; 100}
Javascript
1const mdlOpen = document.querySelectorAll('.js_mdl_open');// 開くボタン 2const mdl = document.querySelectorAll('.js_mdl');// モーダル本体 3const body = document.body; 4 5 //モーダル開くイベント発火 6 mdlOpen.forEach( from => { 7 from.addEventListener("click",function(e){ 8 e.preventDefault(); 9 e.stopPropagation(); 10 body.style.top = -(window.pageYOffset) +'px';//fixedより後にきてはダメ 11 12 const datavalue =from.dataset.mdlopen;//dataset値取得(開く) 13 14 mdl.forEach( (to) => { 15 if( datavalue == to.dataset.mdl){ 16 openModal(to); 17 } 18 })//forEach 19 }) 20 })//forEach 21 22 // モーダル開く 23 function openModal(element){ 24 // 背景固定 25 body.style.position = "fixed"; 26 // モーダル表示 27 element.classList.add('modal_active'); 28 29 //モーダル閉じるイベント発火 30 const closebtn = element.querySelector('.js_mdl_close_icon'); 31 closebtn.addEventListener('click', function(e){ 32 e.stopPropagation(); 33 closeModal(element); 34 }); 35 36 //モーダル閉じるイベント発火 37 addEventListener('click', function(e){ 38 e.stopPropagation(); 39 const mdlWrapper = element.querySelector('.js_mdl_wrapper'); 40 if(e.target == mdlWrapper){ 41 closeModal(element); 42 } 43 }) 44 } 45 46 47 // モーダル閉じる 48 function closeModal(mdl){ 49 // topの値取得 50 const scrollY = body.style.top; 51 // モーダル閉じる 52 mdl.classList.remove('modal_active'); 53 // 背景固定解除 54 body.style.position = ""; 55 56 body.style.top = ''; 57 window.scrollTo({ 58 behavior: "instant", 59 left: 0, 60 top: parseInt(scrollY || '0')*-1 61 }); 62 }
▼修正後
Javascript
1 const mdlOpens = document.querySelectorAll('.js_mdl_open');// 開くボタン 2 const mdls = document.querySelectorAll('.js_mdl');// モーダル本体 3 const body = document.body; 4 5 mdlOpens.forEach( mdlOpen => { 6 //モーダル開くイベント発火 7 mdlOpen.addEventListener("click", e =>{ 8 e.preventDefault(); 9 e.stopPropagation(); 10 11 body.style.top = -(window.pageYOffset) +'px';//fixedより後にきてはダメ 12 const datavalue = mdlOpen.dataset.mdlopen;//dataset.mdlopen 13 14 mdls.forEach( (mdl) => { 15 if( datavalue == mdl.dataset.mdl){//dataset.mdl 16 body.style.position = "fixed"; 17 mdl.classList.add('mdl_active'); 18 19 const closebtn = mdl.querySelector('.js_mdl_close_icon'); 20 const mdlOverlay = mdl.querySelector('.js_mdl_overlay'); 21 22 let scrollY = body.style.top;// topの値取得して変数に格納 23 24 closebtn.addEventListener('click',closeModal); 25 mdlOverlay.addEventListener('click',closeModal); 26 27 // モーダル閉じる 28 function closeModal(){ 29 mdl.classList.remove('mdl_active') 30 body.style.position = ""; 31 body.style.top = ''; 32 window.scrollTo({ 33 behavior: "instant", 34 left: 0, 35 top: parseInt(scrollY || '0')*-1 36 }); 37 };//closeModal 38 }//if 39 })//forEach 40 }) 41 })//forEach


回答1件
あなたの回答
tips
プレビュー