くじらの覚えがき2

おもに勉強ノート、現在ハマっていることなど、不定期で更新しています。書きかけの情報や間違った内容などが掲載されることもありますが、何卒ご容赦ください。

レスポンシブ対応ドロップダウン&ドロワーメニュー

Javascriptを勉強していく中で、今までどうしても自分の鬼門だったレスポンシブ対応のメニューを作ってみることにしました。

PCでは下層メニューがドロップダウンし、スマホではハンバーガーボタンからメニューがスライドインするドロワーメニューになるものです。

ネット上でさがせばいろいろ出てくるのですが、上の条件を完全に満たすものは案外すくなく、ソースも複雑なものが多いです。

それなら自分が納得する形で、ゼロから作ってみようと思いました。

 

作ってみなければわからない点がいくつもありました。

なかでも一番大きな点は、下層メニューを展開させるイベントは、PCとスマホで別に設定しておく、というところ。

第1階層のメニューをクリックすると下層メニューが展開するのであれば条件分岐は必要ないと思いますが、PCではちょっと不親切に感じたので、hover状態で展開するようにしました。

すると、スマホでは下層メニューが開けなくなりました。スマホにはhover状態がないので当然ですね。

このことから、PCではjqueryの.hover()、スマホでは.click()が必要で、そのためにはif文で画面幅を取得して条件分岐する必要がある、とはじめてわかりました。

慣れた人なら当然のことかもしれませんが、他人のソースを読んでいるだけの初心者にはピンときません。自分で作ってみると納得できます。

試行錯誤のうえ、ひとまず動作するようになったソースが以下です。

 

※初心者の試作メモなので動作は保証しません。つっこみどころ満載だと思いますが、つっこまれてもたぶん対応できません。。あしからず。

 

●HTML

  1. <div class="nav-wrap">
  2.   <p class="btn-hb">
  3.     <span></span>
  4.     <span></span>
  5.     <span></span>
  6.     <span>MENU</span>
  7.   </p>
  8.   <nav id="nav-main">
  9.     <ul class="list-root">
  10.       <li class="list-item"> <a class="lv1" href="index.html"><span>MENU1</span></a></li>
  11.       <li class="list-item btn">
  12.         <a class="lv1" href="page1.html"><span>MENU2</span></a>
  13.         <ul class="list-child">
  14.           <li class="sp"><a href="page2.html">MENU2-1</a></li>
  15.           <li><a href="page2.html#main">MENU2-2</a></li>
  16.           <li><a href="page2.html#works">MENU2-3</a></li>
  17.           <li><a href="page2.html#flow">MENU2-4</a></li>
  18.         </ul>
  19.       </li>
  20.       <li class="list-item btn">
  21.         <a class="lv1" href="page3.html"><span>MENU3</span></a>
  22.         <ul class="list-child">
  23.           <li class="sp"><a href="page3.html">MENU3-1</a></li>
  24.           <li><a href="page3.html#about">MENU3-2</a></li>
  25.           <li><a href="page3.html#gaiyou">MENU3-3</a></li>
  26.           <li><a href="page3.html#staff">MENU3-4</a></li>
  27.         </ul>
  28.       </li>
  29.       <li class="list-item"> <a class="lv1" href="page4.html"><span>MENU4</span></a> </li>
  30.     </ul>
  31.   </nav>
  32. </div>

 

Javascript

  1. // PC: hover / dropdown menu
  2. var w = $(window).width();
  3. var x = 767;
  4. if (w > x) {
  5. //console.log("767pxより大きい画面");
  6. $(".list-item.btn").hover(
  7.   function(){
  8.     $(this).children(".list-child").show(200,"linear");
  9.   },
  10.   function(){
  11.     $(this).children(".list-child").hide();
  12.   });
  13. } else {
  14.   //console.log("767pxより小さい画面");
  15.   $(".list-item.btn").on("click",function(e){
  16.     e.preventDefault();
  17.     $(this).children(".list-child").slideToggle();
  18.   });
  19.   $('.list-child li').click(function(event){
  20.     event.stopPropagation();
  21.   });
  22. }
  23. // SP: hamburger menu / drawer menu
  24. $(".btn-hb").on("click",function(){
  25.   $(".btn-hb,#nav-main").toggleClass("show");
  26. });

 

CSS

  1. @charset "UTF-8";
  2. /* ------------------------
  3.  レスポンシブメニュー
  4.  (ドロップダウン&ドロワー)
  5. ------------------------- */
  6. /* line 12, ../scss/respmenu.scss */
  7. .nav-wrap {
  8.   text-align: center;
  9.   background-color: #333;
  10.   -moz-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.2);
  11.   -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.2);
  12.   box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.2);
  13.   filter: progid:DXImageTransform.Microsoft.Shadow(color="#d9d9d9", Direction=145, Strength=5);
  14.   padding: 0;
  15.   margin: 0;
  16.   z-index: 10; }
  17.   /* line 21, ../scss/respmenu.scss */
  18.   .nav-wrap .btn-hb span {
  19.     display: none; }
  20.   /* line 26, ../scss/respmenu.scss */
  21.   .nav-wrap #nav-main {
  22.     width: 1080px;
  23.     margin: 0 auto; }
  24.     /* line 29, ../scss/respmenu.scss */
  25.     .nav-wrap #nav-main .list-root {
  26.       -js-display: flex;
  27.       display: -webkit-box;
  28.       display: -ms-flexbox;
  29.       display: -webkit-flex;
  30.       display: flex;
  31.       -webkit-align-items: center;
  32.       -ms-align-items: center;
  33.       align-items: center;
  34.       -webkit-box-pack: center;
  35.       -moz-box-pack: center;
  36.       -ms-flex-pack: center;
  37.       -webkit-justify-content: center;
  38.       -ms-justify-content: center;
  39.       justify-content: center;
  40.       -webkit-flex-wrap: wrap;
  41.       -ms-flex-wrap: wrap;
  42.       flex-wrap: wrap; }
  43.       /* line 34, ../scss/respmenu.scss */
  44.       .nav-wrap #nav-main .list-root .list-item, .nav-wrap #nav-main .list-root .list-item .list-child li {
  45.         width: 165px;
  46.         position: relative;
  47.         height: 68px; }
  48.         /* line 38, ../scss/respmenu.scss */
  49.         .nav-wrap #nav-main .list-root .list-item a, .nav-wrap #nav-main .list-root .list-item .list-child li a {
  50.           display: block;
  51.           width: 100%;
  52.           margin: 18px 0;
  53.           padding: 0 5px;
  54.           line-height: 1.6;
  55.           height: 32px;
  56.           font-size: 100%;
  57.           color: #fff;
  58.           font-weight: bold;
  59.           text-decoration: none; }
  60.         /* line 50, ../scss/respmenu.scss */
  61.         .nav-wrap #nav-main .list-root .list-item a.lv1 {
  62.           border-right: 1px solid #fff; }
  63.           /* line 52, ../scss/respmenu.scss */
  64.           .nav-wrap #nav-main .list-root .list-item a.lv1:hover span {
  65.             border-bottom: 2px solid #fff; }
  66.         /* line 56, ../scss/respmenu.scss */
  67.         .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 {
  68.           border-right: 0; }
  69.         /* line 59, ../scss/respmenu.scss */
  70.         .nav-wrap #nav-main .list-root .list-item .list-child, .nav-wrap #nav-main .list-root .list-item .list-child li .list-child {
  71.           display: none;
  72.           min-width: 165px;
  73.           position: absolute;
  74.           top: 68px;
  75.           z-index: 9999;
  76.           background-color: rgba(0, 0, 0, 0.8); }
  77.           /* line 68, ../scss/respmenu.scss */
  78.           .nav-wrap #nav-main .list-root .list-item .list-child li {
  79.             padding: 0;
  80.             margin: 0;
  81.             height: auto;
  82.             border: 1px solid #666; }
  83.             /* line 74, ../scss/respmenu.scss */
  84.             .nav-wrap #nav-main .list-root .list-item .list-child li:hover {
  85.               background-color: #000; }
  86.             /* line 77, ../scss/respmenu.scss */
  87.             .nav-wrap #nav-main .list-root .list-item .list-child li a {
  88.               display: block;
  89.               padding: 10px;
  90.               margin: 0;
  91.               height: auto;
  92.               font-weight: normal; }
  93.   @media only screen and (max-width: 1080px) {
  94.     /* line 91, ../scss/respmenu.scss */
  95.     .nav-wrap #nav-main {
  96.       width: 100%; }
  97.       /* line 94, ../scss/respmenu.scss */
  98.       .nav-wrap #nav-main .list-root .list-item, .nav-wrap #nav-main .list-root .list-item .list-child li,
  99.       .nav-wrap #nav-main .list-root .list-item li .list-child {
  100.         width: 15.2777777778%; } }
  101. @media only screen and (max-width: 1080px) and (max-width: 767px) {
  102.   /* line 12, ../scss/respmenu.scss */
  103.   .nav-wrap {
  104.     position: fixed; }
  105.     /* line 103, ../scss/respmenu.scss */
  106.     .nav-wrap .btn-hb {
  107.       position: fixed;
  108.       top: 10px;
  109.       right: 10px;
  110.       width: 40px;
  111.       height: 48px;
  112.       z-index: 13;
  113.       padding: 2px;
  114.       cursor: pointer;
  115.       background-color: rgba(255, 255, 255, 0.8);
  116.       text-align: center; }
  117.       /* line 114, ../scss/respmenu.scss */
  118.       .nav-wrap .btn-hb span {
  119.         display: block;
  120.         width: 100%;
  121.         height: 5px;
  122.         background-color: #333; }
  123.         /* line 119, ../scss/respmenu.scss */
  124.         .nav-wrap .btn-hb span:nth-of-type(1), .nav-wrap .btn-hb span:nth-of-type(2) {
  125.           margin-bottom: 5px; }
  126.         /* line 121, ../scss/respmenu.scss */
  127.         .nav-wrap .btn-hb span:nth-of-type(3) {
  128.           margin-bottom: 5px; }
  129.         /* line 122, ../scss/respmenu.scss */
  130.         .nav-wrap .btn-hb span:nth-of-type(4) {
  131.           font-size: 1.8vw;
  132.           line-height: 1.4;
  133.           background-color: transparent; }
  134.     /* line 129, ../scss/respmenu.scss */
  135.     .nav-wrap #nav-main {
  136.       position: fixed;
  137.       top: 40px;
  138.       right: -200px;
  139.       width: 200px;
  140.       background-color: rgba(0, 0, 0, 0.8);
  141.       z-index: 15;
  142.       opacity: 0;
  143.       -webkit-transition: all 400ms;
  144.       transition: all 400ms; }
  145.       /* line 139, ../scss/respmenu.scss */
  146.       .nav-wrap #nav-main .list-root {
  147.         position: static;
  148.         border: 0;
  149.         padding: 0;
  150.         margin: 0; }
  151.         /* line 144, ../scss/respmenu.scss */
  152.         .nav-wrap #nav-main .list-root .list-item, .nav-wrap #nav-main .list-root .list-item .list-child li {
  153.           width: 100%;
  154.           margin: 0;
  155.           padding: 0;
  156.           height: auto;
  157.           border-bottom: #ccc; }
  158.           /* line 150, ../scss/respmenu.scss */
  159.           .nav-wrap #nav-main .list-root .list-item a.lv1 {
  160.             margin: 0;
  161.             padding: 1em;
  162.             height: auto;
  163.             text-align: left;
  164.             border-right: none; }
  165.             /* line 156, ../scss/respmenu.scss */
  166.             .nav-wrap #nav-main .list-root .list-item a.lv1:hover {
  167.               background-color: #000; }
  168.               /* line 158, ../scss/respmenu.scss */
  169.               .nav-wrap #nav-main .list-root .list-item a.lv1:hover span {
  170.                 border-bottom: 0; }
  171.           /* line 163, ../scss/respmenu.scss */
  172.           .nav-wrap #nav-main .list-root .list-item .list-child, .nav-wrap #nav-main .list-root .list-item .list-child li .list-child {
  173.             width: 100%;
  174.             position: static;
  175.             -webkit-transition: all 150ms;
  176.             transition: all 150ms;
  177.             background-color: transparent; }
  178.             /* line 169, ../scss/respmenu.scss */
  179.             .nav-wrap #nav-main .list-root .list-item .list-child li {
  180.               position: static;
  181.               height: 50px;
  182.               padding: 0;
  183.               border: none; }
  184.               /* line 174, ../scss/respmenu.scss */
  185.               .nav-wrap #nav-main .list-root .list-item .list-child li a {
  186.                 width: 100%;
  187.                 padding: 15px 1em 15px 1.5em;
  188.                 margin: 0;
  189.                 z-index: 16;
  190.                 text-align: left;
  191.                 color: #fff;
  192.                 font-weight: normal; }
  193.     /* line 188, ../scss/respmenu.scss */
  194.     .nav-wrap #nav-main.show {
  195.       opacity: 1;
  196.       transform: translateX(-200px); } }
  197. /*# sourceMappingURL=respmenu.css.map */