jQueryでイベントデリゲーションを使った時と直接要素を指定した時の挙動の違い

jQueryでイベントデリゲーションを使った時と直接要素を指定した時の挙動の違い

21 回閲覧されました

みなさんこんにちは、jonioです。

jQueryを使っている時に下記のコードを見かけました。

('.A').on('click', '.B', function(e) {}

意味を調べるとどうも「Aクラスの中にあるBクラスをクリックした時」という意味みたいなので下記の記述をしても同じ動作をするはずと思いました。

('.A .B').on('click', function(e) {}

しかし違う挙動をしました。

さらに調べると1つ目のコードと2つ目のコードは別物だと分かりました。

そこでメモとしてこの記事を残すことにしました。

イベントデリゲーションでできること

下記の書き方をするのを「イベントデリゲーション」と呼ぶみたいです。

('.A').on('click', '.B', function(e) {}

何ができるかを説明します。

イベントデリゲーションを使わずに下記のコードを書いたとします。

('.A .B').on('click', function(e) {}

このコードでAクラスの中にあるBクラスをクリックした時という意味になりますが「ページを読み込んだ時に表示されている要素に対して」しかクリックが動作しません。

だから何らかの処理をして新しく要素を追加してもページ読み込み時に存在しないのでクリックの処理をすることができません。

下記の簡単なサンプルコードで考えます。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>要素を直接指定</title>
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<body>

<div id="employee-list">
    <button class="select-employee" data-name="山田太郎">山田太郎</button>
    <button class="select-employee" data-name="佐藤花子">佐藤花子</button>
</div>

<div class="user-info"></div>
<button id="add-button">新しい従業員を追加</button>

<script>
$(document).ready(function() {
    $('#employee-list .select-employee').on('click', function(e) {
        e.preventDefault();

        let userName = $(this).data('name');

        $('.user-info').html('<p>名前: ' + userName + '</p>);
    });

    $('#add-button').on('click', function() {
        $('#employee-list').append('<button class="select-employee" data-name="田中一郎" >田中一郎</button>');
    });
});
</script>

</body>
</html>

このコードを書くと「山田太郎」・「佐藤花子」をクリックすると15行目の所に名前が表示されます。

16行目をクリックすると「田中一郎」が「山田太郎」・「佐藤花子」の後ろに追加されますが田中一郎をクリックしても15行目の所に名前が追加されません。

しかし20行目を「(‘#employee-list ‘).on(‘click’, ‘.select-employee’, function(e) {」に変えると田中一郎をクリックした時に15行目の所に名前が表示さます。

このやり方をすればHTMLを動的に追加できます。

まとめ

イベントデリゲーションを使うとページの読み込み後に追加された要素に対してもイベントを使うことができますが直接要素を指定するとページの読み込み時に表示されている要素に対してしかイベントを使うことができません。