javascriptでイベントが取得できなくてイベント委譲しました
一覧表示でDataTableを使っています。
今回は、その中の項目で文字入力してイベントでひってなんて処理を作ってみました。
【HTML側】
1 2 3 4 5 6 7 8 9 |
<td> <label class="text-right col-sm-9" id="<%= data[i].product_cd %>" data-value="<%= data[i].num %>" ><%= data[i].num %></label> </td> <td> <button type="button" class="btn btn-primary" id="btn-<%= data[i].product_cd %>" value="0">在庫追加</button> </td> <td> <input type="number" class="col-sm-5" id="val-<%= data[i].product_cd %>" value="0"> </td> |
【javascript側】
1 2 |
$('button[id^="btn-"]').on('click', function() { } |
こんな感じでやってたんですが、DataTableで絞り込みをした直後はイベントが取得できない事象が発生しました。
Chrome使ってるんですが、デベロッパーコンソールにエラーも何も表示されなくて、ただイベントが取得できない。。。
F5で再表示したら、イベントが取得できる。
こんな現象でした。
こんな時はChatGPTに相談!!
イベントが取得できないんですと相談をしてみたところ、以下の回答がありました。
現状の問題点:取り漏れが発生する原因
$(‘button[id^=”btn-“]’).on(‘click’, …) のように セレクタで複数要素に一括でイベントをバインドする 方法では、以下のようなケースで取り漏れが発生する可能性があります:
1)ボタンが動的に追加される場合
ページの初期描画後に動的に追加されたボタンには、バインドされたイベントが適用されません。
2)DOM の再描画
ボタンが動的に削除・再追加される場合や、Ajax でコンテンツを更新する場合、既存のイベントリスナーが削除されることがあります。
解決策:安定したクリックイベントの設定方法
1. イベント委譲を利用する(推奨)
イベント委譲は、動的に追加される要素でもイベントを確実に処理できます。親要素(静的な要素)にイベントをバインドし、クリックイベントを子要素(ボタン)に委譲します。
2. document.getElementById を利用する
ボタンが静的であり、数がそこまで多くない場合には document.getElementById を使って個別にイベントを設定するのも良い選択肢です。ただし、ボタンが多数ある場合は冗長になりがちです。
3. MutationObserver を利用する
動的な DOM 変更が頻繁に行われる場合は、MutationObserver を使うことで新しく追加されたボタンに確実にイベントを付与できます。
選択肢の比較も作ってくれて、今回は設定の容易さから「イベント委譲を利用する」を採用しました。
どう変えた?
HTML側はtableにidとして”myTable”を追加しました。
というか、DataTableで必要なので設定してありました。
Javascript側を以下の様に修正しました。
$(‘#myTable’).on(‘click’, ‘button[id^=”btn-“]’, function() {
}
DataTableと干渉したりしないかと心配をしましたが、今のところ順調にイベント取得をしてくれています。
持つべきものはAIです(^^)