もっと詳しく

jQueryで実現するメガメニューはたくさんありますが、挙動が合わない、コードが複雑、実装の難易度が高いということがあります。そこで、簡単でいいものを見つけましたのでメモ。

少ないコードでできるサンプルコード

参考サイト

以下のページにあるサンプルコードを試したところ、あっさり実現できました。

試しに作ってみたテストページ

https://qwerty.work/test/test-megamenu.php

マウスオーバーとタッチ(クリック)の両対応したいとき

パソコン用のサイトはマウスホバーで開いてくれるのはいいのですが、スマホやタブレットなど、タッチパネルの場合はタッチまたはクリックで開くようにしなければなりません。私は以下の方法で両対応しました。

JSのソース例

メニューが開いている状態と閉じている状態をflagで判別してjQueryによる開閉動作を行うようにしています。

$(function() {
  var flag = 'close';
  //PCの場合はマウスオーバーで開閉
  $('#menu li').hover(function() {
    $(this).find('.menu_contents').stop().slideDown();
    flag = 'open'; 
  }, function() {
    $(this).find('.menu_contents').stop().slideUp();
    flag = 'close';
  });
  //タブレットの場合はタップで開く
  var clickEventType=((window.ontouchstart!==null)?'click':'touchstart');
  $('#menu li').on(clickEventType,function() {
   if (flag =='close') {
    flag = 'open'; 
    $(this).find('.menu_contents').stop().slideDown();
    event.preventDefault();
   } else {
    flag = 'close';
    $(this).find('.menu_contents').stop().slideUp();
    event.preventDefault(); 
   }
  });
});

クリックで開閉する部分については、以下の書き方でも動きました。

$('.menu_contents').hide();
 $('.menu_list a').click(function(e){
     e.preventDefault();
     // hide all span
     var $this = $(this).parent().find('.menu_contents');
     $('.menu_list .menu_contents').not($this).hide();
     // here is what I want to do
     $this.toggle();
 });

補足

clickとtouchstartイベントが二重に実行されないようにする

clickまたはtouchstartどちらかのイベントで動作させたいとき、以下のように指定することがあります。

$('#menu li').on('click touchstart',function(){

場合によっては1クリックしかしていないに、clicktouchstartが同時に実行され、メニューが一瞬だけ表示され、正常に表示できない場合があります。これを以下のコードでデバイスによってどちらか方法に固定します。

var clickEventType=((window.ontouchstart!==null)?'click':'touchstart');
  $('#menu li').on(clickEventType,function() {

この方法は以下のページを参考にしました。

event.preventDefault();で一時停止させる

ワンクリックや1回のタッチしかしていないのに、どうしてもイベントが多重発生してしまう場合に、以下のコードで一時停止させることができました。

event.preventDefault();

または

eevent.stopPropagation();

この方法は以下のページを参考にしました。


その他のメガメニュー

jQuery-menu-aim

多段で表示できるもの。