本文へスキップ
Build

Column

コラム

制作者向け

WordPressのjQueryが動かない:二重読み込み診断と修正手順

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

WordPressのjQueryが動かない:二重読み込み診断と修正手順 のアイキャッチ

WordPressのハンバーガーメニューを実装したのに、スマホで開かない。
コンソールを開くと「$ is not defined」か「Cannot read properties of null」が出ている。
この状況、原因の大半はjQueryの二重読み込みです。
プラグインを一括無効化して試す前に、DevToolsのNetworkタブを30秒確認するだけで根本を特定できます。
過去のWordPressリニューアル案件で同じ状況に詰まり、DevTools診断からwp_enqueue_scriptの修正で解消した手順をそのまま紹介します。

DevToolsの2ステップでjQuery問題を診断する

DevToolsでjQuery問題を診断するイメージ

コンソールとNetworkタブ、この2点だけで大半の原因が分かります。
順番に確認します。

コンソールでエラーの種類を切り分ける

F12でDevToolsを開き、まずConsoleタブを確認します。
出ているエラーの種類で、その後の対処が変わります。

コンソールエラー

意味

$ is not defined

jQueryが読み込まれていない、または読み込み前に実行

Cannot read properties of null

jQueryは動いているが対象要素が存在しない

jQuery is not defined

jQueryオブジェクト自体が未定義(外部CDN読み込み失敗等)

「$ is not defined」なら、次のステップでjQuery読み込みを確認する。

NetworkタブでjQueryの二重読み込みを確認する

Networkタブを開いてページをリロードし、検索欄に「jquery」と入力して絞り込みます。
リクエスト一覧にjqueryのファイルが複数並んでいれば、二重読み込み確定です。

過去のWordPressリニューアル案件では、ここにjqueryのリクエストが2件並んでいました。
テーマとプラグインがそれぞれ別バージョンのjQueryを読み込んでいたのが原因でした。
Initiator列に表示されているファイルを確認すれば、どのテーマ・プラグインが読み込んでいるか即座に分かります。
プラグイン一括無効化なしで対処できます。

「$ is not defined」はなぜ起きるのか——noConflictと二重読み込み

jQueryの二重読み込みで$ is not definedが発生する概念図

「$ is not defined」の原因は、noConflict()モードとjQuery二重読み込みの組み合わせです。
WordPressは標準でjQueryをnoConflict()モードで読み込みます。
これは$変数を解放し、他のJSライブラリとの衝突を防ぐ設計です。

noConflict()モード下では、$はjQueryと同義ではありません。
jQuery(document).ready(function($) { ... })のように、関数スコープ内で$を明示的に受け取る必要があります。
外側で$()と書いたJSファイルがあると、「$ is not defined」が出ます。
自前のJSがWordPress noConflict()を意識せずに書かれている場合も同様。

二重読み込みが重なるとさらに複雑になります。
流れはこうです。

  1. WordPressが標準jQueryをnoConflict()モードで読み込む
  2. テーマやプラグインが別バージョンのjQueryを独自に追加読み込みする
  3. 追加jQueryがnoConflict()を呼ばず$を上書きする
  4. 他スクリプトが参照していた$の挙動が壊れる

読み込み順序が逆になると、後から来るWordPress標準jQueryが$を上書きする。
このタイミングずれが、特定ページだけ動かないという不安定な症状の正体です。

wp_enqueue_scriptの依存配列で恒久修正する

wp_enqueue_scriptの依存配列で恒久修正する依存チェーンのイメージ

診断で二重読み込みが確認できたら、修正はwp_enqueue_scriptの依存配列で行います。
wp_enqueue_scriptで自前スクリプトを登録する際、依存配列が省略または空配列になっているケースが多いです。

function theme_enqueue_scripts() {
    wp_enqueue_script(
        'my-script',
        get_template_directory_uri() . '/js/my-script.js',
        array( 'jquery' ), // 依存配列に'jquery'を指定
        '1.0.0',
        true // フッターで読み込む
    );
}
add_action( 'wp_enqueue_scripts', 'theme_enqueue_scripts' );

依存配列に'jquery'を指定することで、WordPress標準jQueryを読み込んだ後に自スクリプトを実行します。
これで「$ is not defined」エラーの大半は解消。
自前のJSファイル内では、$を関数の引数で受け取る書き方に統一します。

jQuery(function($) {
    // ここでは $ = jQuery が使える
    $('.hamburger').on('click', function() {
        $('.nav').toggleClass('is-open');
    });
});

wp_deregister_scriptを使う修正が危険な理由

検索するとwp_deregister_script('jquery')でWordPress標準jQueryを削除してから再登録する方法が出てきます。
しかしこれは主要プラグインを壊すリスクがあります。

WooCommerceやContact Form 7など広く使われているプラグインは、WordPress標準のjQueryハンドルに依存しています。
標準jQueryを削除すると、それらプラグインのJS機能が動かなくなります。
依存配列の修正だけで解決する場合は、wp_deregister_scriptには手を出さないほうが安全です。

プラグイン競合の絞り込み方

Networkタブで二重読み込みを確認したら、Initiator列から原因プラグインを特定できます。
プラグインを一括無効化して個別に有効化する方法より、Initiator列から直接絞り込むほうが早いです。

  • そのプラグインの設定でjQuery読み込みを無効化する(設定にある場合)
  • functions.phpでwp_dequeue_script('対象ハンドル名')を使い、競合jQueryだけ除外する

後者はプラグイン全体を無効化しないため、他の機能を維持したまま競合だけ取り除けます。
ハンバーガーメニュー(ドロワーメニュー)の実装方法でjQueryを使ったドロワーメニューのコード全体を参照できます。

まとめ

  • コンソールの「$ is not defined」→ jQueryの読み込み問題と切り分ける
  • NetworkタブでjQueryリクエストが複数→Initiator列で原因特定してから対処
  • wp_enqueue_scriptの依存配列['jquery']が恒久修正の正解
  • wp_deregister_scriptは主要プラグインを壊すリスクがあるため避ける

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