レスポンシブ対応ドロップダウン&ドロワーメニュー
Javascriptを勉強していく中で、今までどうしても自分の鬼門だったレスポンシブ対応のメニューを作ってみることにしました。
PCでは下層メニューがドロップダウンし、スマホではハンバーガーボタンからメニューがスライドインするドロワーメニューになるものです。
ネット上でさがせばいろいろ出てくるのですが、上の条件を完全に満たすものは案外すくなく、ソースも複雑なものが多いです。
それなら自分が納得する形で、ゼロから作ってみようと思いました。
作ってみなければわからない点がいくつもありました。
なかでも一番大きな点は、下層メニューを展開させるイベントは、PCとスマホで別に設定しておく、というところ。
第1階層のメニューをクリックすると下層メニューが展開するのであれば条件分岐は必要ないと思いますが、PCではちょっと不親切に感じたので、hover状態で展開するようにしました。
すると、スマホでは下層メニューが開けなくなりました。スマホにはhover状態がないので当然ですね。
このことから、PCではjqueryの.hover()、スマホでは.click()が必要で、そのためにはif文で画面幅を取得して条件分岐する必要がある、とはじめてわかりました。
慣れた人なら当然のことかもしれませんが、他人のソースを読んでいるだけの初心者にはピンときません。自分で作ってみると納得できます。
試行錯誤のうえ、ひとまず動作するようになったソースが以下です。
※初心者の試作メモなので動作は保証しません。つっこみどころ満載だと思いますが、つっこまれてもたぶん対応できません。。あしからず。
●HTML
- <div class="nav-wrap">
- <p class="btn-hb">
- <span></span>
- <span></span>
- <span></span>
- <span>MENU</span>
- </p>
- <nav id="nav-main">
- <ul class="list-root">
- <li class="list-item"> <a class="lv1" href="index.html"><span>MENU1</span></a></li>
- <li class="list-item btn">
- <a class="lv1" href="page1.html"><span>MENU2</span></a>
- <ul class="list-child">
- <li class="sp"><a href="page2.html">MENU2-1</a></li>
- <li><a href="page2.html#main">MENU2-2</a></li>
- <li><a href="page2.html#works">MENU2-3</a></li>
- <li><a href="page2.html#flow">MENU2-4</a></li>
- </ul>
- </li>
- <li class="list-item btn">
- <a class="lv1" href="page3.html"><span>MENU3</span></a>
- <ul class="list-child">
- <li class="sp"><a href="page3.html">MENU3-1</a></li>
- <li><a href="page3.html#about">MENU3-2</a></li>
- <li><a href="page3.html#gaiyou">MENU3-3</a></li>
- <li><a href="page3.html#staff">MENU3-4</a></li>
- </ul>
- </li>
- <li class="list-item"> <a class="lv1" href="page4.html"><span>MENU4</span></a> </li>
- </ul>
- </nav>
- </div>
●Javascript
- // PC: hover / dropdown menu
- var w = $(window).width();
- var x = 767;
- if (w > x) {
- //console.log("767pxより大きい画面");
- $(".list-item.btn").hover(
- function(){
- $(this).children(".list-child").show(200,"linear");
- },
- function(){
- $(this).children(".list-child").hide();
- });
- } else {
- //console.log("767pxより小さい画面");
- $(".list-item.btn").on("click",function(e){
- e.preventDefault();
- $(this).children(".list-child").slideToggle();
- });
- $('.list-child li').click(function(event){
- event.stopPropagation();
- });
- }
- // SP: hamburger menu / drawer menu
- $(".btn-hb").on("click",function(){
- $(".btn-hb,#nav-main").toggleClass("show");
- });
●CSS
- @charset "UTF-8";
- /* ------------------------
- レスポンシブメニュー
- (ドロップダウン&ドロワー)
- ------------------------- */
- /* line 12, ../scss/respmenu.scss */
- .nav-wrap {
- text-align: center;
- background-color: #333;
- -moz-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.2);
- -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.2);
- box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.2);
- filter: progid:DXImageTransform.Microsoft.Shadow(color="#d9d9d9", Direction=145, Strength=5);
- padding: 0;
- margin: 0;
- z-index: 10; }
- /* line 21, ../scss/respmenu.scss */
- .nav-wrap .btn-hb span {
- display: none; }
- /* line 26, ../scss/respmenu.scss */
- .nav-wrap #nav-main {
- width: 1080px;
- margin: 0 auto; }
- /* line 29, ../scss/respmenu.scss */
- .nav-wrap #nav-main .list-root {
- -js-display: flex;
- display: -webkit-box;
- display: -ms-flexbox;
- display: -webkit-flex;
- display: flex;
- -webkit-align-items: center;
- -ms-align-items: center;
- align-items: center;
- -webkit-box-pack: center;
- -moz-box-pack: center;
- -ms-flex-pack: center;
- -webkit-justify-content: center;
- -ms-justify-content: center;
- justify-content: center;
- -webkit-flex-wrap: wrap;
- -ms-flex-wrap: wrap;
- flex-wrap: wrap; }
- /* line 34, ../scss/respmenu.scss */
- .nav-wrap #nav-main .list-root .list-item, .nav-wrap #nav-main .list-root .list-item .list-child li {
- width: 165px;
- position: relative;
- height: 68px; }
- /* line 38, ../scss/respmenu.scss */
- .nav-wrap #nav-main .list-root .list-item a, .nav-wrap #nav-main .list-root .list-item .list-child li a {
- display: block;
- width: 100%;
- margin: 18px 0;
- padding: 0 5px;
- line-height: 1.6;
- height: 32px;
- font-size: 100%;
- color: #fff;
- font-weight: bold;
- text-decoration: none; }
- /* line 50, ../scss/respmenu.scss */
- .nav-wrap #nav-main .list-root .list-item a.lv1 {
- border-right: 1px solid #fff; }
- /* line 52, ../scss/respmenu.scss */
- .nav-wrap #nav-main .list-root .list-item a.lv1:hover span {
- border-bottom: 2px solid #fff; }
- /* line 56, ../scss/respmenu.scss */
- .nav-wrap #nav-main .list-root .list-item:last-of-type a.lv1, .nav-wrap #nav-main .list-root .list-item .list-child li:last-of-type a.lv1 {
- border-right: 0; }
- /* line 59, ../scss/respmenu.scss */
- .nav-wrap #nav-main .list-root .list-item .list-child, .nav-wrap #nav-main .list-root .list-item .list-child li .list-child {
- display: none;
- min-width: 165px;
- position: absolute;
- top: 68px;
- z-index: 9999;
- background-color: rgba(0, 0, 0, 0.8); }
- /* line 68, ../scss/respmenu.scss */
- .nav-wrap #nav-main .list-root .list-item .list-child li {
- padding: 0;
- margin: 0;
- height: auto;
- border: 1px solid #666; }
- /* line 74, ../scss/respmenu.scss */
- .nav-wrap #nav-main .list-root .list-item .list-child li:hover {
- background-color: #000; }
- /* line 77, ../scss/respmenu.scss */
- .nav-wrap #nav-main .list-root .list-item .list-child li a {
- display: block;
- padding: 10px;
- margin: 0;
- height: auto;
- font-weight: normal; }
- @media only screen and (max-width: 1080px) {
- /* line 91, ../scss/respmenu.scss */
- .nav-wrap #nav-main {
- width: 100%; }
- /* line 94, ../scss/respmenu.scss */
- .nav-wrap #nav-main .list-root .list-item, .nav-wrap #nav-main .list-root .list-item .list-child li,
- .nav-wrap #nav-main .list-root .list-item li .list-child {
- width: 15.2777777778%; } }
- @media only screen and (max-width: 1080px) and (max-width: 767px) {
- /* line 12, ../scss/respmenu.scss */
- .nav-wrap {
- position: fixed; }
- /* line 103, ../scss/respmenu.scss */
- .nav-wrap .btn-hb {
- position: fixed;
- top: 10px;
- right: 10px;
- width: 40px;
- height: 48px;
- z-index: 13;
- padding: 2px;
- cursor: pointer;
- background-color: rgba(255, 255, 255, 0.8);
- text-align: center; }
- /* line 114, ../scss/respmenu.scss */
- .nav-wrap .btn-hb span {
- display: block;
- width: 100%;
- height: 5px;
- background-color: #333; }
- /* line 119, ../scss/respmenu.scss */
- .nav-wrap .btn-hb span:nth-of-type(1), .nav-wrap .btn-hb span:nth-of-type(2) {
- margin-bottom: 5px; }
- /* line 121, ../scss/respmenu.scss */
- .nav-wrap .btn-hb span:nth-of-type(3) {
- margin-bottom: 5px; }
- /* line 122, ../scss/respmenu.scss */
- .nav-wrap .btn-hb span:nth-of-type(4) {
- font-size: 1.8vw;
- line-height: 1.4;
- background-color: transparent; }
- /* line 129, ../scss/respmenu.scss */
- .nav-wrap #nav-main {
- position: fixed;
- top: 40px;
- right: -200px;
- width: 200px;
- background-color: rgba(0, 0, 0, 0.8);
- z-index: 15;
- opacity: 0;
- -webkit-transition: all 400ms;
- transition: all 400ms; }
- /* line 139, ../scss/respmenu.scss */
- .nav-wrap #nav-main .list-root {
- position: static;
- border: 0;
- padding: 0;
- margin: 0; }
- /* line 144, ../scss/respmenu.scss */
- .nav-wrap #nav-main .list-root .list-item, .nav-wrap #nav-main .list-root .list-item .list-child li {
- width: 100%;
- margin: 0;
- padding: 0;
- height: auto;
- border-bottom: #ccc; }
- /* line 150, ../scss/respmenu.scss */
- .nav-wrap #nav-main .list-root .list-item a.lv1 {
- margin: 0;
- padding: 1em;
- height: auto;
- text-align: left;
- border-right: none; }
- /* line 156, ../scss/respmenu.scss */
- .nav-wrap #nav-main .list-root .list-item a.lv1:hover {
- background-color: #000; }
- /* line 158, ../scss/respmenu.scss */
- .nav-wrap #nav-main .list-root .list-item a.lv1:hover span {
- border-bottom: 0; }
- /* line 163, ../scss/respmenu.scss */
- .nav-wrap #nav-main .list-root .list-item .list-child, .nav-wrap #nav-main .list-root .list-item .list-child li .list-child {
- width: 100%;
- position: static;
- -webkit-transition: all 150ms;
- transition: all 150ms;
- background-color: transparent; }
- /* line 169, ../scss/respmenu.scss */
- .nav-wrap #nav-main .list-root .list-item .list-child li {
- position: static;
- height: 50px;
- padding: 0;
- border: none; }
- /* line 174, ../scss/respmenu.scss */
- .nav-wrap #nav-main .list-root .list-item .list-child li a {
- width: 100%;
- padding: 15px 1em 15px 1.5em;
- margin: 0;
- z-index: 16;
- text-align: left;
- color: #fff;
- font-weight: normal; }
- /* line 188, ../scss/respmenu.scss */
- .nav-wrap #nav-main.show {
- opacity: 1;
- transform: translateX(-200px); } }
- /*# sourceMappingURL=respmenu.css.map */