【jQuery】イベントリスナーが効かない時のよくある原因3選
jQueryはイベントを設置する際などに手軽に活用できるJavaScriptライブラリですが、如何せんよくわからない不具合を起こすことがしばしあります。
中でも多いのが、イベントリスナーが効かないトラブルです。
今回は、イベントリスナーが効かないトラブルの原因について、数年の間に経験したよくある原因を3つご紹介します。
1. セレクタの指定ミス
jQueryを扱う上で、最もありがちなミスの一つと言えるのが、セレクタの指定ミスです。
例えば、以下のコードはbutton要素をクリックした際にログを出力するだけの簡単なプログラムですが、絶対に動くことはありません。
<body>
<button type="button" class="sample-target"></button>
<script>
// コンソールに何も表示されない!
$("sample-target").on("click", function(){
console.log("ok");
});
</script>
</body>
動かない原因としては、セレクタを指定する際に、class名を示す接頭辞である「.」が抜けているだけです。
// 「.」をつけ足せば動く
$(".sample-target").on("click", function(){ (中略)
このミスの落とし穴は、エラーログが出力されないことです。
jQueryのセレクタ問題に関して、jQueryやブラウザ側がエラーログを出力することはありません。
セレクタの指定は文字列として行いますし、該当する要素がないケースも普通に存在することから、こういったミスをエラーとして捉えるよう設計されていないのです。
上記の端的なプログラムなら発見も容易なものの、複数のJSファイルからなるプログラムであったり、PHPなどサーバサイドの処理と合わせて一度に実装、テストして動かなかったりした場合には、この小さな間違いに気づくまで時間がかかることがよくあります。
「完璧なプログラムだ。どこも間違っていない。なぜ動かない?」と思考停止し始めた時には、セレクタの指定を深く見直していくのが良いでしょう。
一応、有料IDEを利用したり、専用のプラグインを追加したりして、補完機能などを有効活用すれば、ある程度このミスは回避できます。
2. 対象の要素がロードされていない
これは初心者の方にありがちな話ですが、対象の要素がロードされていない状態でイベントリスナーを設置しようとしているというミスをしていることも珍しくありません。
この「要素のロード」は文章の単純さに反して説明するのが非常に面倒な事象ですので、ここでは詳しく解説はしません。
ただ、理解しておくべきなのは「HTMLタグをブラウザがDOMに変換するまで時間がかかる」ということです。
イベントリスナーはDOMで管理するものなので、DOMが作られるまでの間にイベントリスナーを設置しようとすると、当然セレクタで指定した要素が見つからず、イベントリスナーの設置に失敗します。
この事象を簡単に再現できるのが、対象とする要素のHTMLタグより先にイベントリスナーの記述を行っている場合です。
以下のコードをご覧ください。
<body>
<script>
// 先にイベント設置
$(".sample-target").on("click", function(){
console.log("ok");
});
</script>
// 後に要素読み込み
<button type="button" class="sample-target">動かない!?</button>
</body>
セレクタの指定などにもミスはありませんが、対象の要素がイベント設置処理よりも後に記述されています。
HTMLやJSは、ファイルの先頭から下へ向かって順に読まれるため、イベント設置処理よりも後にHTMLタグが記述されているということは、当然イベント設置時には対象の要素が存在しない状態です。
したがって、上記のコードではどれだけボタンを押してもイベントが反応しません。
当然、エラーコードも出力されないので、発見が遅れやすい定番のミスです。
後から追加される要素にイベントを設置したい場合
昨今のWEB制作ではHTMLタグをはじめから全て直書きするのは稀で、基本的にはJSを使い、ユーザの操作に合わせて後から要素を追加することがよくあります。
しかし、前述の話からすると、後から追加する要素にclickイベントを設置する場合はどうするのかとなりますよね。
その場合は、以下のように第三引数まで指定する方法で対応します。
<script>
/* 後から追加する要素も対象にできる */
$(document).on("click", ".sample-target", function(){
console.log("ok");
});
</script>
<button type="button" class="sample-target">動く!</button>
コードの記述量は増えますが、ミスを減らすならこの記述でイベントを設置する方が無難です。
3. 「$」が有効でない
jQueryを使おうとすると、珍しくエラーログが出力されるときがあります。
例えば、以下のようなログです。

「$ is not a function」というエラーですが、要するにこれは
「$(“.sample-target”)と関数呼ぼうとしてるけど、function $() なんて関数定義されてないよ!」
と怒られています。
jQueryの「$(セレクタ名)」の記法が使えない状態になっているわけです。
この状態になる原因としては、主に以下の2つがあります。
- jQueryライブラリを読み込めていない
- 「$」が他の機能と重複してしまっている
それぞれの原因について、少し詳しく見ていきましょう。
原因1. jQueryライブラリを読み込めていない
当然ですが、「$」というのはjQuery側で提供されている機能であり、jQueryが読み込めていない状態では意味を成しません。
イベントリスナーの際にも説明したように、HTMLファイルは先頭から順にリソースを読み込むため、jQueryライブラリを読み込む前に「$」を使うとエラーになります。
<script>
/* エラーになる */
$(document).on("click", ".sample-target", function(){
console.log("ok");
});
</script>
<!-- jQueryライブラリ読み込み -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
また、上記コードのようにjQueryをCDNで呼び出している場合、CDNサーバ側の問題で取得に失敗している可能性もあります。
現に、jQueryのライブラリが上手く読み込めず、各所のサイトで不具合が起きることは今までに何度かありました。
「どう考えてもコードは間違っていない」という場合は、一度公式サイトからjQueryライブラリのminファイル等をDLして、それを取り込んで動作確認するのが良いかもしれません。
原因2. 「$」が他の機能と重複してしまっている
jQueryは基本的にどの命令も「$」を使って宣言しますが、実はこの「$」が他のライブラリやフレームワークなどと重複してしまうことがあります。
他のライブラリやフレームワークが「$」で関数を実行できたりするような場合ですね。
例として代表的なのが、ブログサイトの開発によく用いられているWordPressです。
実は、WordPressでは標準的な機能として「$」を用いた処理の実行処理を取り入れているため、WordPress上で「$」を使うと、どの「$」を呼ばれたのかシステム側が判断できず、エラーが発生します。
この問題の対処法として、よく用いられているのが「$」を「jQuery」に置き換える手法です。
<script>
/* $ を jQuery に変更 */
jQuery(document).on("click", ".sample-target", function(){
console.log("jqueryok");
});
</script>
実はjQueryの構文は「$」ではなく「jQuery」で宣言しても処理の内容に変わりはありません。
jQueryライブラリ以外で「jQuery」と宣言する機能を実装することはないため、この方法であればどの環境でも宣言名が競合しないのです。
まとめ
jQueryは汎用的なライブラリですが、開発者にとって親切ではない部分があるのも事実です。
「あれ?なんで動かないんだ?」となったときは、ここで解説した内容を参考にしながら、注意深く原因を調査すると良いでしょう。