ジャンルから探す

Web Design English

jQueryでドロップダウンメニューを実装する5つの方法

この記事では、jQueryを使ってドロップダウンメニューを実装する5つの方法を紹介します。

結論から書くと、動きを付けたいなら slideUp/slideDown、CSSで見た目を管理したいなら addClass/removeClass を選びます。どれもHTMLは共通で、切り替え方だけが違います。

▼5つの方法の使い分け

方法 動き 開くきっかけ
slideUp/slideDown スライド ホバー
addClass/removeClass CSS次第 ホバー
fadeIn/fadeOut フェード ホバー
toggleClass CSS次第 ホバー
slideToggle スライド クリック

読み込むjQueryのバージョンに注意してください。3.5.0より前のjQueryにはXSSの脆弱性(CVE-2020-11022 / CVE-2020-11023)があります。この記事のコードは3.7.1を読み込む形に更新しました。公開するサイトで使う場合は、必ず3.5.1以降を読み込んでください。

スポンサーリンク

jQueryのslideUp/slideDownを使う

jQueryのslideUp/slideDownを使ったドロップダウンメニューの実装がこちら。

HTML

クラス「.menuSub」の部分が、マウスホバーした時に表示される内容です。

<div>
  <ul class="menu">
    <li>menu1</li>
    <li>
      menu2
      <ul class="menuSub">
        <li><a href="#">menu2-1</a></li>
        <li><a href="#">menu2-2</a></li>
      </ul>
    </li>
    <li>
      menu3
      <ul class="menuSub">
        <li><a href="#">menu3-1</a></li>
        <li><a href="#">menu3-2</a></li>
        <li><a href="#">menu3-3</a></li>
      </ul>
    </li>
  </ul>
</div>
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>

CSS

クラス「.menuSub」に「display: none;」を設定して非表示にしておきます。表示・非表示の切り替えは、jQueryの処理によって切り替わります。

その他のCSSは、見た目を整えるための設定です。

.menu {
  display: flex;
  justify-content: flex-start;
  list-style-type: none;
  color: #fff;
  padding: 0;
}

.menu li {
  position: relative;
  width: 100px;
  margin-left: 1px;
  padding: 5px;
  background: #444444;
}

.menuSub {
  position: absolute;
  margin-left: -6px;
  padding: 0;
  display: none;
}

.menuSub li a {
  padding: 5px;
  margin-left: -5px;
  margin-right: -5px;
  margin-bottom: -5px;
  display: block;
  color: #fff;
  text-decoration: none;
}

.menuSub li a:hover {
  background: #FFCA7B;
}

jQuery/JS

「.menu li」をマウスホバーすると、slideDown()で「.menuSub」が表示されます。マウスホバーが外れると、slideUp()で「.menuSub」が非表示になります。

「:not(:animated)」の記述は必須です。この記述をしておくことで、アニメーション実行中にマウスホバーされても処理が追加されないようになります。

  $(function() {
    $("ul.menu li").hover(
      function() {
        $(".menuSub:not(:animated)", this).slideDown();
      },
      function() {
        $(".menuSub", this).slideUp();
      }
    );
  });

jQueryのaddClass/removeClassを使う

jQueryのaddClass/removeClassを使ったドロップダウンメニューの実装はこちら。

HTML

クラス「.menuSub」の部分が、マウスホバーした時に表示される内容です。

<div>
  <ul class="menu">
    <li>menu1</li>
    <li>
      menu2
      <ul class="menuSub">
        <li><a href="#">menu2-1</a></li>
        <li><a href="#">menu2-2</a></li>
      </ul>
    </li>
    <li>
      menu3
      <ul class="menuSub">
        <li><a href="#">menu3-1</a></li>
        <li><a href="#">menu3-2</a></li>
        <li><a href="#">menu3-3</a></li>
      </ul>
    </li>
  </ul>
</div>
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>

CSS

ポイントが2つあります。

クラス「.menuSub」に「display: none;」を設定して非表示にしておく
クラス「.menuSub.open」に「display: block;」を設定して、ホバー時に表示される

②の「.menuSub.open」は、マウスホバー時に、jQueryで「.menuSub」に「.open」を追加する処理を実装します。

その他のCSSは、見た目を整えるための設定です。

.menu {
  display: flex;
  justify-content: flex-start;
  list-style-type: none;
  color: #fff;
  padding: 0;
}

.menu li {
  position: relative;
  width: 100px;
  margin-left: 1px;
  padding: 5px;
  background: #444444;
}

.menuSub {
  position: absolute;
  margin-left: -6px;
  padding: 0;
  display: none;
}

/*.openが付与された時、表示の設定*/
.menuSub.open {
  display: block;
}

.menuSub li a {
  padding: 5px;
  margin-left: -5px;
  margin-right: -5px;
  margin-bottom: -5px;
  display: block;
  color: #fff;
  text-decoration: none;
}

.menuSub li a:hover {
  background: #FFCA7B;
}

jQuery/JS

マウスホバーされると、addClass()で「.menuSub」に「.open」を追加します。CSSの設定で「.menuSub.open」を表示する設定を記述しているので、メニューが表示される仕組みになってます。

マウスホバーが外れると、removeClass()で「.open」を削除します。CSSの設定で「.menuSub」を非表示にする設定を記述しているので、メニューが非表示となります。

  $(function() {
    $(".menu li").hover(
      function() {
        //クラス名「open」を付与する
        $(this).children(".menuSub").addClass("open");
        //hoverが外れた場合
      }, function() {
        //クラス名「open」を取り除く
        $(this).children(".menuSub").removeClass("open");
      }
    );
  });

スポンサーリンク

jQueryのfadeIn/fadeOutを使う

この方法では、fadeInfadeOutを使って、メニューの表示・非表示を滑らかなフェードアニメーションで制御します。これにより、ドロップダウンメニューの表示がより視覚的に心地よくなります。hoverイベントでフェード効果を適用し、ユーザーがメニューにマウスを乗せたときにサブメニューが徐々に表示され、マウスを外すと徐々に消える動作を実現します。

jQueryのfadeIn/fadeOutを使う

フェードで表示・非表示を切り替える実装です。スライドではなく透明度が変化します。

HTML

<div>
  <ul class="menu">
    <li>menu1</li>
    <li>
      menu2
      <ul class="menuSub">
        <li><a href="#">menu2-1</a></li>
        <li><a href="#">menu2-2</a></li>
      </ul>
    </li>
    <li>
      menu3
      <ul class="menuSub">
        <li><a href="#">menu3-1</a></li>
        <li><a href="#">menu3-2</a></li>
        <li><a href="#">menu3-3</a></li>
      </ul>
    </li>
  </ul>
</div>
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>

CSS

.menu {
  display: flex;
  justify-content: flex-start;
  list-style-type: none;
  color: #fff;
  padding: 0;
}

.menu li {
  position: relative;
  width: 100px;
  margin-left: 1px;
  padding: 5px;
  background: #444444;
}

.menuSub {
  position: absolute;
  margin-left: -6px;
  padding: 0;
  display: none;
}

.menuSub li a {
  padding: 5px;
  margin-left: -5px;
  margin-right: -5px;
  margin-bottom: -5px;
  display: block;
  color: #fff;
  text-decoration: none;
}

.menuSub li a:hover {
  background: #FFCA7B;
}

jQuery/JS

$(function() {
  $(".menu li").hover(
    function() {
      $(this).children(".menuSub").fadeIn();
    },
    function() {
      $(this).children(".menuSub").fadeOut();
    }
  );
});

スポンサーリンク

jQueryのtoggleClassを使う

この方法では、toggleClassを使って、サブメニューの表示・非表示を制御します。hoverイベントに応じてopenクラスを追加・削除することで、CSSで定義したスタイルを適用または解除します。これにより、状態の切り替えが非常に簡単になり、コードの可読性とメンテナンス性が向上します。

jQueryのtoggleClassを使う

クラスの付け外しを1つのメソッドにまとめた実装です。addClass/removeClassを2回書く必要がなくなります。

HTML

<div>
  <ul class="menu">
    <li>menu1</li>
    <li>
      menu2
      <ul class="menuSub">
        <li><a href="#">menu2-1</a></li>
        <li><a href="#">menu2-2</a></li>
      </ul>
    </li>
    <li>
      menu3
      <ul class="menuSub">
        <li><a href="#">menu3-1</a></li>
        <li><a href="#">menu3-2</a></li>
        <li><a href="#">menu3-3</a></li>
      </ul>
    </li>
  </ul>
</div>
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>

CSS

.menu {
  display: flex;
  justify-content: flex-start;
  list-style-type: none;
  color: #fff;
  padding: 0;
}

.menu li {
  position: relative;
  width: 100px;
  margin-left: 1px;
  padding: 5px;
  background: #444444;
}

.menuSub {
  position: absolute;
  margin-left: -6px;
  padding: 0;
  display: none;
}

.menuSub.open {
  display: block;
}

.menuSub li a {
  padding: 5px;
  margin-left: -5px;
  margin-right: -5px;
  margin-bottom: -5px;
  display: block;
  color: #fff;
  text-decoration: none;
}

.menuSub li a:hover {
  background: #FFCA7B;
}

jQuery/JS

$(function() {
  $(".menu li").hover(
    function() {
      $(this).children(".menuSub").toggleClass("open");
    },
    function() {
      $(this).children(".menuSub").toggleClass("open");
    }
  );
});

jQueryのslideToggleを使う

slideToggleは、要素の表示・非表示をスライドアニメーションで切り替えるメソッドです。この方法では、clickイベントに反応してサブメニューをスライド表示または非表示にします。スライド効果を用いることで、ユーザーに視覚的な手がかりを与え、メニューの開閉がより直感的に感じられるようにしています。

jQueryのslideToggleを使う(クリックで開閉)

ここまでの4つはマウスホバーで開きますが、これはクリックで開閉します。タッチ端末でも動く実装です。

HTML

<div>
  <ul class="menu">
    <li>menu1</li>
    <li>
      menu2
      <ul class="menuSub">
        <li><a href="#">menu2-1</a></li>
        <li><a href="#">menu2-2</a></li>
      </ul>
    </li>
    <li>
      menu3
      <ul class="menuSub">
        <li><a href="#">menu3-1</a></li>
        <li><a href="#">menu3-2</a></li>
        <li><a href="#">menu3-3</a></li>
      </ul>
    </li>
  </ul>
</div>
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>

CSS

.menu {
  display: flex;
  justify-content: flex-start;
  list-style-type: none;
  color: #fff;
  padding: 0;
}

.menu li {
  position: relative;
  width: 100px;
  margin-left: 1px;
  padding: 5px;
  background: #444444;
}

.menuSub {
  position: absolute;
  margin-left: -6px;
  padding: 0;
  display: none;
}

.menuSub li a {
  padding: 5px;
  margin-left: -5px;
  margin-right: -5px;
  margin-bottom: -5px;
  display: block;
  color: #fff;
  text-decoration: none;
}

.menuSub li a:hover {
  background: #FFCA7B;
}

jQuery/JS

$(function() {
  $(".menu li").click(function() {
    $(this).children(".menuSub").slideToggle();
  });
});

ホバーで開く実装の弱点と対処

結論:ホバーで開くドロップダウンは、タッチ端末とキーボード操作で開けません。公開するサイトで使うなら、クリック開閉かキーボード対応を足してください。

スマートフォンやタブレットには「ホバー」がありません。タップすると1回目でホバー扱いになる端末もありますが、挙動はブラウザによってばらつきます。確実に動かすなら、5つ目の slideToggle のようにクリックで開閉する実装を選びます。

キーボードだけで操作する人も、ホバーできないため開けません。次のようにフォーカスでも開くようにしておくと、Tabキーで到達できるようになります。

$(function () {
  $(".menu li").on("mouseenter focusin", function () {
    $(this).children(".menuSub").slideDown();
  });
  $(".menu li").on("mouseleave focusout", function () {
    $(this).children(".menuSub").slideUp();
  });
});

focusinfocusout は、子要素へのフォーカス移動も拾ってくれるイベントです。focus / blur では子要素のリンクにフォーカスが移った時点で閉じてしまうので、こちらを使います。

支援技術に状態を伝えるには、aria-expanded を付けます。開いているかどうかが読み上げられるようになります。

<button aria-expanded="false" aria-controls="submenu2">menu2</button>
<ul class="menuSub" id="submenu2">
  <li><a href="#">menu2-1</a></li>
</ul>

jQueryを使わない選択肢

結論:ドロップダウンだけのためにjQueryを読み込む必要はありません。CSSだけ、あるいは標準のHTML要素でも作れます。

CSSだけで作る場合は、隣接する要素を :hover で表示します。JavaScriptを一切読み込まずに済みます。

.menu li .menuSub {
  display: none;
}

.menu li:hover .menuSub,
.menu li:focus-within .menuSub {
  display: block;
}

:focus-within を併記しておくと、キーボード操作でも開きます。主要ブラウザはすべて対応しています。

クリックで開閉するアコーディオン的なメニューなら、HTMLの <details><summary> がそのまま使えます。JavaScriptもCSSも書かずに開閉し、キーボード操作にも最初から対応しています。

<details>
  <summary>menu2</summary>
  <ul>
    <li><a href="#">menu2-1</a></li>
    <li><a href="#">menu2-2</a></li>
  </ul>
</details>

▼どれを選ぶか

状況 選ぶもの
すでにjQueryを使っている この記事の5つの方法
アニメーションが要らない CSSのみ(:hover:focus-within
クリックで開閉したい <details> / <summary>
細かい制御が要る 素のJavaScript

まとめ

この記事では、jQueryを使ってドロップダウンメニューを実装するさまざまな方法をご紹介しました。

  1. slideUp/slideDownaddClass/removeClassを使う方法
    アニメーションを伴ったスライド効果でメニューの開閉を制御します。
  2. toggleClassを使う方法
    シンプルにクラスの追加と削除を行い、瞬時にメニューを表示・非表示にします。
  3. slideToggleを使う方法
    スライドアニメーションを簡潔に実装でき、クリックイベントでメニューの状態を切り替えます。
  4. fadeIn/fadeOutを使う方法
    フェード効果でメニューの表示・非表示を滑らかに制御します。

それぞれの方法は、メニューの動きやユーザー体験に応じて選択できます。アニメーションの効果を強調するか、シンプルに状態を切り替えるかは用途によって異なるため、必要に応じて自由にカスタマイズし、適切な方法を選んでください。ぜひ、自分のプロジェクトに合った実装を試してみてください。

メニュー以外のインタラクションも実装したい場合は、マウスストーカーの作り方CSSとjQueryでアコーディオンを実装するもあわせてどうぞ。どちらも「クラスを付け外しして見た目を変える」という同じ考え方で作れます。

HTML/CSS/JavaScriptを基礎から固めたい場合は、Webコーディングにオススメの学習本に学習順をまとめています。