本文へスキップ
Build

Column

コラム

jQueryのハンバーガーメニューが動かない:3ステップ診断と直し方

この記事には広告リンクを含みます。紹介している商品・サービスの一部はアフィリエイトプログラムを利用しています。 商品・サービスの選定はご自身の判断でお願いいたします。

jQueryのハンバーガーメニューが動かない:3ステップ診断と直し方 のアイキャッチ

jQueryのコードを貼り付けたのに、ハンバーガーメニューが動かない。
原因を特定できずに時間だけが過ぎていく、という経験は制作者なら一度はあると思います。
動かない原因は大きく「全ページで動かないケース」と「特定ページだけ動かないケース」に分かれます。
DevToolsの3タブを順番に確認するだけで、どちらに当たるかが自分の経験では5分以内に切り分けられることが多い。
切り分けが終われば修正方針はほぼ決まるので、まずConsoleを開く癖をつけておくと作業効率がかなり変わります。

ConsoleタブとElementsタブで原因を絞り込む

DevToolsでハンバーガーメニューの不具合を調査する場面

ハンバーガーメニューが動かないと気づいたら、最初にConsoleタブを開きます。
F12(MacはOption + Command + I)でDevToolsを開き、Consoleタブを選びます。
エラーの有無と文言で、原因の大半は絞り込めます。

Consoleの状態

疑うべき原因

$ is not definedが出ている

jQuery本体が読み込まれていない

Cannot read properties of nullが出ている

特定ページでDOMが存在しない

エラーなし、メニューが動かない

セレクタ名のズレかタイミングずれ

エラーなしの場合:セレクタ名を照合する

Consoleにエラーが出ていない場合は、セレクタ名のズレを疑います。
ElementsタブでHTMLの実際のクラス名を確認し、JSのセレクタと照合します。
Ctrl + F(MacはCommand + F)でクラス名を検索すると確実。
30秒ほどで照合できます。

// HTML側のクラス名
<button class="nav-toggle"></button>

// JSのセレクタがズレていると動かない
$('.menu-btn').click(...); // nav-toggleと一致していない

タイミングずれや$ is not definedの場合

全ページで動かないのにConsoleにエラーがなく、セレクタも合っている場合は実行タイミングを疑います。
DOMが読み込まれる前にJSが実行されていると、セレクタが正しくても動きません。
scriptタグをbodyの末尾に移動するか、DOMContentLoadedでラップすると解消するケースが多いです。
ConsoleにjQueryの$ is not definedが出ていて全ページで動かない場合は、jQueryの読み込み自体に問題があります。
WordPressでの対処は別途まとめています。
ConsoleにjQuery $ is not definedが出る場合はこちら

「特定ページのみ動かない」はDOMのNullエラーが原因

全ページで動かないならjQueryの読み込みかセレクタの問題ですが、特定ページだけ動かない場合は原因が別です。
ConsoleにCannot read properties of nullが出ていたら、このケースに当たります。
DOMが存在しないページにJSが実行されている状態です。

以前関わった保守案件で、このパターンに遭遇しました。
特定のページでだけハンバーガーメニューが動かないという報告で、他のページでは問題がない状況でした。
Consoleを見るとCannot read properties of nullが出ていました。
調べると、そのページだけテーマがナビゲーションのHTMLを出力していませんでした。
querySelectorがnullを返し、そのnullにaddEventListenerを呼び出すためエラーになっていた流れです。

jQueryの$()はセレクタが存在しなければ無言でスキップします。
querySelectorは同じ状況でnullを返し、そこにメソッドを呼ぶとエラーになります。
両者が混在しているコードは、エラーが出る箇所と出ない箇所が入り混じるため、原因が分かりにくい。

直し方はif文でガードするだけです。

const toggleBtn = document.querySelector('.nav-toggle');
if (toggleBtn) {
  toggleBtn.addEventListener('click', function() {
    document.querySelector('.nav-menu').classList.toggle('is-open');
  });
}

このif文を入れると、DOMが存在しないページではJSがスキップされ、エラーが止まります。
特定ページのみ動かない報告が来たら、まずそのページのConsoleを開いて確認するのが最短ルートです。

修正後に確認する3点セット

修正したらすぐ本番を確認する前に、次の3点をセットで押さえます。

  1. 全ページでハンバーガーメニューが開閉するか
  2. スマホ実機での動作確認(複数機種があれば理想)
  3. ConsoleのエラーがゼロになっているかをDevToolsで確認

Consoleゼロを目標にする習慣は、修正の取りこぼしを防ぐ観点で効果があります。
1つのページでJSエラーを放置すると、他の機能に干渉するケースもあるためです。

全ページ確認のとき、トップページだけでなく下層ページや特定のカテゴリページも確認するのが安全です。
今回の保守案件のように、特定ページだけ挙動が変わるケースがあるためです。

スマホ実機確認は面倒に感じることもあるが、自分が関わった案件では、スマホ表示が崩れたままのページで問い合わせが止まっていたことがある。
スマホで問い合わせページまで3タップ以内で到達できるかも合わせて確認しておくと保守品質が上がります。
スマホ導線の問題が問い合わせ数に影響するケースは、リニューアル後に効果が出ない事例でも触れています。

まとめ

  • まずConsoleタブでエラーの有無と文言を確認する
  • エラーなし → ElementsタブでセレクタをCtrl + F検索で照合
  • 特定ページのみCannot read properties of null → if文ガードで解消
  • $ is not defined → jQueryの読み込み問題として切り分ける
  • 修正後は全ページ・スマホ実機・Consoleゼロの3点確認

コーディング代行・実装判断で詰まったら、Buildに振ってください。