ある日、いつも通りjQueryを使っているとコンソールに次のエラーメッセージが・・・
1 |
xxx.php:7 Uncaught ReferenceError: $ is not defined |
こういう $ is not defined エラーってjQueryを使ってると頻繁というほどでもないけど、よく見かけることが多いですよね。
でも実はこのエラーは大したものでなく、少しコードを直せば簡単に解決できます。
ここではエラーの原因とコード修正のやり方について具体的なコード例と一緒にまとめました。
このエラーが出てしまう原因
ずばり $ is not defined エラーの原因を一言でいうなら
jQueryで読み込まれてない段階でjQuery関数を使おうとしているから
たったこれだけの単純な理由です。
例えばエラーが出てしまうのは次みたいなコード例
1 2 3 4 5 6 7 8 9 10 |
<!-- jQuery読み込み前に実行 --> <script> $(function(){ $('#hoge').html('CANNOT execute'); }); </script> <!-- jQueryをCDNから読み込み --> <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"> </script> |
scriptタグを使ってjQueryをCDNで読み込む前にjQuery関数($で始まるやつ)を実行しようとしてしまっています。これなら $ is not defined エラーが出てしまうのは当然ですよね。
ただし上の例はエラーが出る原因をものすごく単純化したもの
実際は次のような要因が複雑に絡まってエラーが発生してしまいます。
- WordPressなどのCMSの影響
- PHPでの呼び出しタイミング
特にWordPressだとjQuery読み込み後に実行しているのに、 $ is not defined エラーが起こることもしばしば・・・そういう時に正しい対処法を知らないと遠回りな方法を試したりで時間が無駄になります。
でも実はこのエラー、対処するのはとても簡単です。
このエラーへの簡単な対処法
その対処法とはjQueryのおまじないとして書かれる次の部分を少し書き換えるだけ
1 2 3 |
$(function(){ /** jQueryの処理 */ }); |
この部分を次のようにjQueryを使わずに書き換えすると動作するようになります。
1 2 3 |
window.addEventListener('DOMContentLoaded', function(){ /** jQueryの処理 */ }); |
ウィンドウに対して 'DOMContentLoaded' というDOMが構築されたときに発火するイベントに実行したいコールバックを登録すればいいだけ。
こうしておけばjQueryが読み込まれる前でも影響を受けないので問題なく処理が実行できるという訳です。(動作的には $(function(){}) と全く同じ)
ただし上の DOMContentLoaded はHTML要素が解析されたすぐ後に実行されるので、CSSや画像の読み込み完了は待たずに実行されます。
なのでページ全部が読み込まれた後に実行したいなら onload を使う方が最適(次コード)
1 2 3 |
window.onload = function(){ /** jQueryの処理 */ }; |
こういう風に書けば画像のサイズを測ったり、CSSが適用された後の要素に対してjQueryで操作する、といったことができるようになります。
ここまでのまとめ
ということで $ is not define エラーの原因と解決法でした。
もしこのエラーが出てしまった場合は次の2つのどちらかで対処しましょう。
- JSのDOMContentLoadedイベントを使う
次のようにDOMContentLoadedイベントにコールバック登録すればOK
123window.addEventListener('DOMContentLoaded', function(){/** jQueryの処理 */});ちなみにこのイベントはDOMが構築された直後に呼ばれる(画像やCSSは含まない)
- JSのonloadイベントを使う
次のようにonloadイベントにjQuery実行するコールバック登録すればOK
123window.onload = function(){/** jQueryの処理 */};ちなみにこのイベントはDOMに加え、画像やCSSなどの読み込み後に実行される
個人的にはjQuery単体というよりもPHPとかと組み合わせて発生することが多いような気がします。そういう場合にこの対処法が役に立つはずです。