いつもteratailでお世話になっております。みなさまのお力を借りさせていただきたく、質問させていただきます。
下記の仕様でスマホのグローバルナビゲーションを作成しております。
が、javascriptのスキルが低いこともあり、全くうまくいかず・・・
■仕様
・ボタンAをクリック(タップ)するとボタンAの内容が、ボタンBだとボタンBの内容がオーバーレイとともに現れる
・オーバーレイをクリックすると非表示になる
・背景はスクロールしたくない
・ボタンAとBだけ追従(ボタンの位置をすぎるとfixed)
・fixed中は下スクロールで非表示、上スクロールで表示
という盛り沢山な仕様・・・
このようなマークアップをしております。
html
1 <header> 2 ~~~ 3 </header> 4 5 <div id="nav" class="nav"> 6 7 <div class="Head_block"> 8 <h1>タイトル</h1> 9 <div class="btns"> 10 <button class="btnA btn"> 11 ボタンA 12 </button> 13 <button class="btnB btn"> 14 ボタンB 15 </button> 16 </div> 17 18 <div class="menu_wrap"> 19 <div class="contents contentA"> 20 ボタンAの内容 21 </div> 22 </div> 23 </div><!-- /.irHead_block --> 24 25 <div class="menu_wrap"> 26 <nav id="contentB" class="contents contentB"> 27 <ul id="parentNav" class="parentNav"> 28 <li> 29 リスト 30 </li> 31 </ul> 32 </nav> 33 </div> 34 <div class="ovarlay"></div> 35 36 </div><!-- /.nav --> 37 38 <div class="contents"> 39 ~~~ 40 </div>
■いろいろかいつまんで実装としようとした際に参考にしたサイト達
https://blog-and-destroy.com/7519
https://haniwaman.com/header-fixed/
https://tips.adrec-dept.com/html-css/208/
http://nekohand.tokyo/background-fixed/
javascriptのコードを教えていただけるのが一番嬉しいですが、
このサイトやプラグインを参考にしたら?や、こういう考え方でコードを書いたら?などアドバイスが
ありましたら何卒教えてくださいm(__)m
どうぞよろしくお願いいたします
====
追記です。
現状のjsです。大体は実装できたようですが、細かいところがうまくいかず・・・
javascript
1(function($) { 2 3 $(function(){ 4 // ボタンのDOM要素を取得 5 var btn = document.getElementsByClassName('btn'); 6 var contentsB = $('.contentB'); 7 var contentA = $('.contentA'); 8 9 // ボタンの個数分ループ 10 // 変数「i」に現在のループ回数が代入される 11 for (var i = btn.length - 1; i >= 0; i--) { 12 btnAction(btn[i],i); 13 } 14 15 function btnAction(btnDOM,btnId){ 16 17 // 各ボタンをイベントリスナーに登録 18 btnDOM.addEventListener("click", function(){ 19 20 this.classList.toggle('active'); 21 22 // クリックされていないボタンにactiveがついていたら外す 23 for (var i = btn.length - 1; i >= 0; i--) { 24 if(btnId !== i){ 25 if(btn[i].classList.contains('active')){ 26 btn[i].classList.remove('active'); 27 } 28 } 29 if($('.contentB').hasClass('active')){ 30 contentsB.show(); 31 $('.ovarlay').addClass('is-hide'); 32 }else{ 33 contentsB.hide(); 34 } 35 if($('contentA').hasClass('active')){ 36 contentA.show(); 37 $('.ovarlay').addClass('is-hide'); 38 }else{ 39 contentA.hide(); 40 } 41 } 42 }) 43 } 44 45 $('.ovarlay').on('click', function() { 46 $('.btn').removeClass('active'); 47 $('.ovarlay').removeClass('is-hide'); 48 $('body').removeClass('body-fixed'); 49 50 if($('.btnA').removeClass('active')){ 51 contentsB.hide(); 52 } 53 if($('.btnB').removeClass('active')){ 54 contentA.hide(); 55 } 56 }); 57 }); 58 59$(function () { 60 var flag = false; 61 $('.btn , .ovarlay').on('click', function () { 62 if (flag == false) { 63 bodyFix(); // bodyを固定させる関数 64 // その他、ナビを開くときに起きるあれこれを記述 65 $('body').addClass('body-fixed'); 66 flag = true; 67 }else if(flag == true && $('.btn').hasClass('active')){ 68 $('body').addClass('body-fixed'); 69 flag = true; 70 }else { 71 closeNavi(); 72 $('body').removeClass('body-fixed'); 73 flag = false; 74 } 75 }); 76 77}); 78//ナビを閉じるときの関数 79function closeNavi() { 80 $('body').removeClass('body-fixed'); 81 bodyFixReset(); // body固定を解除する関数 82 // その他、ナビを閉じるときに起きるあれこれを記述 83} 84//以下、bodyを固定する関数 85var bodyElm = $('body'); 86var scrollPosi; 87 88function bodyFix() { 89 scrollPosi = $(window).scrollTop(); 90 bodyElm.css({ 91 'position': 'fixed', 92 'width': '100%', 93 'z-index': '1', 94 'top': -scrollPosi 95 }); 96} 97//以下、body固定を解除する関数 98function bodyFixReset() { 99 bodyElm.css({ 100 'position': 'relative', 101 'width': 'auto', 102 'top': 'auto' 103 }); 104 $('.ovarlay').removeClass('is-hide'); 105 //scroll位置を調整 106 $('html, body').scrollTop(scrollPosi); 107} 108 109 /*-------------- scrolldown --------------*/ 110 $(function() { 111 var nav = $('#nav'); 112 var navPos = nav.offset().top; // グローバルメニューの位置 113 var height = $('.Head_block').innerHeight(); 114// var childNav = $('.childNav'); 115 var showClass = 'is-show'; 116 var startPos = 0; 117 var winScrollTop = 0; 118 119 $(window).on('load scroll',function(){ 120 winScrollTop = $(this).scrollTop(); 121 122 if ( winScrollTop > navPos) { 123 nav.addClass(showClass); 124 125 } else { 126 nav.removeClass(showClass); 127 } 128 if($(this).scrollTop() < startPos ){ 129 //上スクロール時の処理 130 nav.removeClass('is-down').css({transform: 'translateY(0)'}); 131 }else if(nav.hasClass('is-show')){ 132 //下スクロール時の処理 133 nav.css({transform: 'translateY('+ -height + 'px)'}); 134 } 135 startPos = $(this).scrollTop(); 136 }); 137 }); 138 139 140})(jQuery);
css
1.nav { 2 position: relative; 3 z-index: 2; 4 background: #FFF; 5} 6.nav .nav_menu_wrap { 7 position: relative; 8} 9.nav .Head_block { 10 background: #FFF; 11} 12.nav .Head_block h1 { 13 padding: 4% 6.25%; 14 font-size: 6.875vw; 15 font-weight: bold; 16} 17.nav .btns { 18 background: #333; 19 position: relative; 20 text-align: center; 21} 22.nav .btns .btnA { 23 display: inline-block; 24 width: 14%; 25 height: 100%; 26 padding: 4% 0; 27 position: absolute; 28 top: 0; 29 left: 0; 30} 31.nav .btns .btnA svg { 32 fill: #FFF; 33} 34.nav .btns .btnA.active { 35 background: #8b8b8b; 36} 37.nav .btns .btnB { 38 display: inline-block; 39 width: 100%; 40 height: 100%; 41 padding: 4% 0; 42 color: #FFF; 43 font-weight: bold; 44} 45.nav .btns.btn { 46 cursor: pointer; 47} 48.nav .contentA { 49 display: none; 50 background: #8b8b8b; 51 width: 100%; 52 padding: 6.25%; 53 box-sizing: border-box; 54 position: absolute; 55} 56.nav .contentA form { 57 background: #ebe8e8; 58 padding: 3% 5%; 59 border-radius: 10px; 60 position: relative; 61} 62.nav .contentA form .search { 63 position: absolute; 64 top: 50%; 65 right: 5%; 66 transform: translate(0%, -50%); 67} 68.nav .contentA form .search svg { 69 fill: #8b8b8b; 70} 71.nav .contentB { 72 display: none; 73 width: 100%; 74 position: absolute; 75 z-index: 1; 76} 77.nav .contentB li { 78 border-top: solid 1px #d8d8d8; 79 background: #333; 80} 81.nav .contentB li a { 82 display: inline-block; 83 color: #FFF; 84 font-weight: bold; 85 width: 100%; 86 padding: 3% 4%; 87 box-sizing: border-box; 88 position: relative; 89} 90.nav .contentB li a:after { 91 content: ""; 92 display: block; 93 width: 0; 94 height: 0; 95 border-style: solid; 96 border-width: 5px 0 5px 9px; 97 border-color: transparent transparent transparent #FFF; 98 position: absolute; 99 right: 4%; 100 top: 50%; 101 transform: translate(0%, -50%); 102} 103.nav.is-show { 104 position: fixed; 105 top: 0; 106 left: 0; 107 z-index: 2; 108 width: 100%; 109 transition: .3s; 110} 111.nav.is-show:before, .nav.is-show:after { 112 content: none; 113} 114 115.ovarlay { 116 position: absolute; 117 top: 0; 118 left: 0; 119 width: 100%; 120 height: 100vh; 121 background: rgba(0, 0, 0, 0.5); 122 z-index: -1; 123 display: none; 124} 125.ovarlay.is-hide { 126 display: block; 127} 128 129.body-fixed .nav:before, .body-fixed .nav:after { 130 content: none; 131} 132.body-fixed .nav .contentB { 133 position: fixed; 134 top: 0; 135 width: 100%; 136 height: 100%; 137 overflow: scroll; 138 -webkit-overflow-scrolling: touch; 139} 140.body-fixed h1 { 141 display: none; 142} 143 144@media only screen and (max-width: 768px) { 145 .nav.is-show h1 { 146 display: none; 147 } 148} 149@media screen and (min-width: 768px) { 150 .nav .Head_block { 151 position: relative; 152 max-width: 1280px; 153 padding: 35px 10px; 154 margin: 0 auto; 155 box-sizing: border-box; 156 } 157 .nav .Head_block h1 { 158 padding: 0; 159 font-size: 22px; 160 line-height: 1.0; 161 } 162 .nav .btns { 163 display: none; 164 } 165 .nav .contentA { 166 display: block !important; 167 background: none; 168 padding: 0; 169 width: 22%; 170 max-width: 280px; 171 position: absolute; 172 top: 50%; 173 right: 10px; 174 transform: translate(0%, -50%); 175 } 176 .nav .contentB { 177 display: block !important; 178 position: relative; 179 background: #333; 180 } 181 .nav .contentB ul { 182 max-width: 1280px; 183 margin: 0 auto; 184 padding: 7px 10px; 185 } 186 .nav .contentB ul li { 187 border-top: none; 188 display: inline-block; 189 font-size: 1.09375vw; 190 } 191 .nav .contentB ul li a { 192 padding: 7px 10px; 193 transition: .3s; 194 } 195 .nav .contentB ul li a:after { 196 content: none; 197 } 198 .nav .contentB ul li.is-open a { 199 position: relative; 200 } 201} 202
どうぞよろしくお願いいたしますm(__)m
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/01/28 03:30