jQueryでイベントが発火しないときの簡単な対処法

ボタンにイベントを設定したはずなのに発火しない
チェックボックスにチェックが入ってもイベントが起きない

こういう風になぜかイベントが発火しないことはjQueryを使っているとちょくちょく遭遇します。

しかもエラーも出ないし、DOMの読み込み後にイベントを設定してるのに関わらずです。

という訳でイベントが発火しないときの簡単にできる対処法について紹介

イベントが発火しないのはなぜ?

まずなんでイベントが発生しないのか?

ということですが、それは単純にイベントハンドラが登録されていないからです。

そもそもイベントハンドラが登録されてなければイベントは発火しようがありません。

 

ではどういうときにイベントが未登録になってしまうのか・・・

それは動的にボタンやチェックボックスなどの部品を追加したときです。

これだけだと分かりにくいので少し例を使って説明します。

 

例えば次のようなHTMLを作成したとしましょう。

そしてこの中で 'add_click_btn_btn' というIDを持つボタンが押されたときに、div要素内に 'clickme_btn' と同じボタンを動的に追加したいとします。

 

そしてそのために次のようなjQueryコードを書きました。

このコードでやりたいことは

  • ボタン(add_clickme_btn_btn)が押されたらボタン(clickme_btn)追加
  • ボタン(clickme_btn)が押されたらアラート表示

という2つです。

1番目のボタンの追加処理については問題なくできます。

しかし2番目のアラート表示については追加されたボタンでは上手くいきません。

 

具体的にどういう風に動くかは次のCodePenを参照

See the Pen 【jQuery】イベントが動作しない悪い例 by ぴー助 (@pisuke-code) on CodePen.

Add Button」をクリックした後に追加されたボタンを押せば何も起こらないことが分かるはずです。

このように動的に追加された要素だとイベントが発火しないことが起こります。

 

ではなぜイベントが発火しないかというとその原因が次のコード

これが期待通りに動くのはイベント登録した要素が既にDOM上に存在する場合だけです。

もし動的に追加された要素でもイベント登録したいなら少し工夫する必要があります。

イベントが発火しないときの対処法

では動的に追加したボタンなどでイベントが発火しないときはどうすればいいか・・・

その答えは document に対してイベントを登録することです。

例えば次のような感じで

$(document).on のようにウェブページ全体に対してイベントハンドラを登録します。

そして  on  の2番目の引数にイベント処理したいボタンなどの要素のセレクタを書けばOK

 

先ほどのボタン追加の例でいうなら次のように書き直せば期待通りに動作します。

これでドキュメント全体でクリックイベントが受け取れ、その発生元が '.clickme_btn' だった時にイベントが発生するようになります。

 

実際にどのように動くかについては次のCodePenを見てください。

See the Pen 【jQuery】イベントが動作しない場合の解決策 by ぴー助 (@pisuke-code) on CodePen.

動的に追加したボタンでもアラートが表示されるようになっています。

ここまでのまとめ

ということでここまでのことを簡単にまとめると次の通り

  • イベントが発火しない原因
    動的に追加した要素だとイベントハンドラが登録されないから
  • イベントが発火しないときの対処法
    要素そのものでなくdocument全体でイベントを受け取る

Web開発してると動的に要素を追加する場面って意外と多いんですよね。

そういう時にイベントが起こらない場合は 「documento全体でイベントを受ける」⇒「イベント処理する要素を絞り込み」のようにすれば上手くいきます。

 

ということでjQueryでイベントが発火しないときの対処法でした。

ではでは・△・)ノ バイバイ

Shareこの記事をシェアしよう!

Commentsこの記事についたコメント

8件のコメント
  • hmk

    大変参考になりました!ありがとうございます。

    12月 12, 2019 11:12 am
    • ぴー助

      この記事がお役に立ったようで嬉しいです。
      コメントありがとうございました!

      12月 12, 2019 2:14 pm
  • TAICHI

    大変参考になりました!

    7月 5, 2020 8:29 pm
    • ぴー助

      記事が参考になったようで嬉しいです。
      コメントありがとうございます!

      7月 6, 2020 12:02 pm
  • ちょこぱい

    この記事のおかげで本当に助かりました。
    なかなかこういう記事がなくて感謝いたします。

    6月 28, 2021 11:34 am
    • ぴー助

      記事がお役に立てたようで嬉しいです。
      コメントありがとうございました!

      6月 28, 2021 3:09 pm
  • あぶらあげ

    若干語弊があるのでコメント。$(“セレクタ”)は実行時にセレクタで指定された要素のみを対象にするため、それ以降の要素の変化を監視するわけではありません。追加したボタンのクリックイベントが発火しないのは追加されたボタンにイベントを登録していないのが原因です。

    次のように修正することで期待通りの動作をするかと思います(ローカルで確認済み)。$(“DOM要素の記述”)でDOM要素を作成してイベント登録などの処理を行ってからappendメソッドで挿入するのがポイントです。

    /** イベント処理用関数 **/
    function clickEvent(){alert(‘Button is clicked’);}

    /** イベント登録処理 **/
    $(function(){
    /** 追加されるボタンにイベントを追加 */
    $(‘.clickme_btn’).click(clickEvent);

    /** ボタンの追加処理 */
    $(‘#add_clickme_btn_btn’).click(function(){
    /** ボタンを作成 **/
    let newButton = $(‘Click Me’);
    /** イベントを登録 **/
    newButton.click(clickEvent);
    /** ボタンを追加 **/
    $(‘#btns_box’).append(newButton);
    });
    });

    7月 11, 2021 1:46 am
  • あぶらあげ

    <と>でエスケープされていなかったので修正。

    /** ボタンを作成 **/
    let newButton = $(‘<button class=”clickme_btn”>Click Me</button>’);

    7月 11, 2021 1:55 am

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA


このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください