【jquery】解決!追加した要素だとイベント(on)が発生しない!?

このような問題を解決

削除
削除
追加

まず、上の表の「削除」をクリックしてみてください。どちらをクリックしても削除できるかと思います。※最後の1つは削除できないようにしています

次に、「追加」をクリックしてください。1つ上の行と同じ行が追加されます。追加された要素の「削除」をクリックしてください。削除できません。追加された要素も削除できるよう対応します。

結論から言います

イベント処理に使用する「on」の指定の仕方の違いです。

$('.delete-row').on('click', function() {

こちらの場合、追加された要素ではイベント(例だとクリック)が発生しません。

$('body').on('click', '.delete-row', function() {

こちらの場合ですと、追加された要素でもイベント(例だとクリック)が発生します。

修正は2か所です。$(‘.delete-row’)$(‘body’)に変更します。※親要素へ変更しています。親であればだれでもOK

次に、親に変更した$(‘.delete-row’)の要素部分’.delete-row’をイベントの後ろに引数として追加します。見た方が分かりやすいですね。「on(‘click’, function」→「on(‘click’, ‘.delete-row’, function」と追加してください。

以上で、解決します。

修正後

削除
削除
追加

追加して削除してみてください。削除できるようになっています。

onについて(イベントの後ろの引数)

親要素に変更する点は特に気にならないかと思います。

イベントの後ろに引数を追加しましたが、こちらの引数にはセレクタを指定することができます。今回だと(‘.delete-row’)です。つまり対象要素としては$(‘body .delete-row’)ということです。

セレクタで指定した場合は、追加要素でも対象になるんですね。

おそらく…

前者の場合は、ページ表示時に対象要素を確定させているのでしょう。よって、要素が追加されたとしても、対象要素に加える処理が存在しないのだと思います。後者の場合はセレクタ部分はページ表示時ではなく、イベント発生時に探し直すのだと思われます。

つまり、処理としては前者の方が早いかもしれないですね。ケースによって使い分けると良いかもしれないです。

参考までにソースを書いておきます

cssは動作には関係ありませんので割愛します。htmlは共通です。

HTML

<table><tbody>
    <tr>
        <td><input type="number" name="age" value="25" />歳</td>
        <td><input type="text" name="name" value="たろう" /></td>
        <td><span class="delete-row">削除</span></td>
    </tr>
    <tr>
        <td><input type="number" name="age" value="25" />歳</td>
        <td><input type="text" name="name" value="はなこ" /></td>
        <td><span class="delete-row">削除</span></td>
    </tr>
    <tr>
        <td colspan="3"><span class="add-row">追加</span></td>
    </tr>
</tbody></table>

javascript

javascriptです。「add-row」のイベント処理は全く同じです。

期待通り動かないソース

<script>
jQuery(document).ready(function($){
    // 行を追加します
    $('.add-row').on('click', function() {
        var add = $(this).parents('tr').prev().clone();
        $(this).parents('tr').before(add);
    });
    // 行を削除します(追加要素は削除できない)
    $('.delete-row').on('click', function() {
        var len = $(this).parents('table').find('tr').length;
        if (len < 3) {
            alert('最後の1つは削除できません')
            return;
        }
        $(this).parents('tr').remove();
        run();
    });
});
</script>

期待通り動くソース

<script>
jQuery(document).ready(function($){
    // 行を追加します
    $('.add-row').on('click', function() {
        var add = $(this).parents('tr').prev().clone();
        $(this).parents('tr').before(add);
    });
    // 行を削除します(追加要素は削除できる)
    $('body').on('click', '.delete-row', function() {
        var len = $(this).parents('table').find('tr').length;
        if (len < 3) {
            alert('最後の1つは削除できません')
            return;
        }
        $(this).parents('tr').remove();
        run();
    });
});
</script>