[忘備録]ajaxのonで指定してイベントが2回目に動かない時


発生した課題

- ("#指定したID").on("イベント名",fuction())がページを読み込んで1回目は動作するが、2回目では動作しないことで実装につまづいた

  • 実装が汚い気がするが対応が完了したので忘備録として保存

自称発生時のコード

  • table内に配置された<a>タグボタンを押したら、押した行が削除される機能をajaxで実装していた
  • ページを読み込んで1回目は動作するが、2回目以降onclickイベントを含め、発火がしなかった
問題発生時erbファイル
<% @user_todo_list.each do | todo |  %>
                    <tr>
                        <th><%= format_date(todo.clear_plan) %></th>
                        <th><%= todo.title%></th>
                        <th><%= todo.weight%></th>
                        <th><%= todo.set_count%></th>
                        <th><%= link_to "完了", complete_todo_path(todo), class:"btn btn-sm btn-primary", id:"complete-link", method: :patch, remote: true,data:{confirm: "完了ずみとして登録しますか?"}%></th>
                    </tr>
                <% end%>
問題のjavascriptファイル
function complete_todo(){
    var completed_td_row = "";

    complete_link.on("click", function(){
        completed_td_row = $(this).parent().parent()[0];
    });

    complete_link.on("ajax:success", function(event){
        var data = event.detail[0].data;
        var flash = event.detail[0].flash;
        console.log(data);
        //table行番号を取得
        completed_td_row.remove();
        //グラフの更新
        show_graph();
    });

    complete_link.on("ajax:error",function(){
        var error_messages = event.detail[0].errors;
        var flash = event.detail[0].flash
    });


}
$(document).on('turbolinks:load', complete_todo);

原因

  • $(ID or 変数 or class).onを指定した場合htmlが描画される時しか関連づかないらしい
  • つまり2回目にボタンを押しても、すでに描画されている要素をクリックしているため発火しない

解消策

  • $(body).on(イベント名, "id",function(){}で解決した

- キャッシュが原因しているっぽい?(GETメソッドではキャッシュする情報を得たがPATCHメソッドもキャッシュする?)

修正後javascriptファイル
function complete_todo(){
    var completed_td_row = "";

    $("body").on("click","#complete-link", function(){
        completed_td_row = $(this).parent().parent()[0];
    });

    $("body").on("ajax:success","#complete-link", function(event){
        var data = event.detail[0].data;
        var flash = event.detail[0].flash;
        console.log(data);
        //table行の削除
        completed_td_row.remove();
        //グラフの更新
        show_graph();
    });

    $("body").on("ajax:error","#complete-link",function(){
        var error_messages = event.detail[0].errors;
        var flash = event.detail[0].flash
    });


}
$(document).on('turbolinks:load', complete_todo);

まとめ

  • railsアプリ作成中にonで詰まってしまったので忘備録として記録
  • 正確な理由についてまだ調査中のため判明したら追記します。