Deep Insider の Tutor コーナー
>>  Deep Insider は本サイトからスピンオフした姉妹サイトです。よろしく! 
jQuery逆引きリファレンス

jQuery逆引きリファレンス

文書ツリー上に存在しない要素に対してイベントリスナーを追加するには?(on)

2015年4月23日

onメソッドを利用して、動的に新規追加された要素にイベントリスナーを設置する方法を解説。またjQuery 1.6以前のbind/live/delegateメソッドをonメソッドに置き換える方法も説明する。

  • このエントリーをはてなブックマークに追加

 onメソッドを利用することで、現時点では文書ツリー上に存在しない要素に対しても、イベントリスナーを設置できます。例えば、以下はボタンをクリックするたびに、ボタン自身が増殖していく例です。

HTML
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>jQuery TIPS</title>
</head>
<body>
<div id="parent">
  <button class="btn">プラス</button>
</div>
<script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
<script>
$(function() {
  $('#parent').on(
    'click',   // イベント名
    '.btn',    // 子要素セレクター
    function() {
      $('<button class="btn">プラス</button>')
        .appendTo('#parent');
    }
  );
});
</script>
</body>
</html>
ボタンクリックのたびにボタンが増えていくコード(on_second.html)
既存の[プラス]ボタンをクリック

既存の[プラス]ボタンをクリック

追加された[プラス]ボタンをクリック

追加された[プラス]ボタンをクリック

[追加]ボタンをクリックするたびに、ボタンが増えていく
[追加]ボタンをクリックするたびに、ボタンが増えていく

 このとき、元からあったボタンだけでなく、あとから追加されたボタンをクリックしても、同じようにボタンが増えることを確認してください(イベントリスナーを追加した時点で存在しない要素に対しても、イベントリスナーが追加されているのです)。

 このようなイベントリスナーを追加するには、onメソッドの以下の構文を利用します。

[構文]onメソッド

$('親セレクター').on('イベント名', '子セレクター', function(e) {
……イベント発生時の処理……
})

 これによって、「親セレクター配下の子セレクターで示された要素に対して、イベントリスナーを設置する」という意味になります。上のサンプルでも、$()関数には、ボタンそのものではなく、ボタンの上位の<div>要素が渡されていることを確認してください。イベントリスナーが対象の要素そのものではなく、コンテナー要素(親要素)によって管理されるので、配下の子要素が増減しても、そのイベントを監視できるわけです。

 別稿で示したonメソッドと、今回のものとの違いを図示すると次のようになります。

onメソッドの挙動内容(別稿のパターン/本稿のパターン)

 もしも(<div id="parent">要素ではなく)ページ全体の<button class="btn">要素をイベント監視の対象としたいならば、$(document) に対してイベントリスナーを設置してください。これは次のコードのようになります。

JavaScript
$(document).on(
  'click',
  '.btn',
  function() {
    $('<button class="btn">プラス</button>')
      .appendTo('#parent');
  }
);
ページ全体の<button class="btn">要素を監視したい場合

 この構文には、もうひとつ、パフォーマンス上のメリットもあります。というのも、先ほどの図を見ても分かるように、前回の書き方では1つ1つの要素に対してイベントリスナーを設置していました。しかし、この構文では、子要素の数にかかわらず、イベントリスナーそのものはコンテナー要素1つに対して設置されるだけです。

 その性質上、特に何十、何百にも及ぶ要素をイベント監視の対象とするケースでは*1、本稿の構文を利用することで、リスナー登録のオーバーヘッドを軽減できます。

  • *1 例えば行数、セル数の多いテーブルにリスナーを登録するようなケースです。

補足:jQuery 1.6以前のメソッド

 onメソッドは、jQuery 1.7以上で追加された比較的新しいメソッドです。jQuery 1.6以前では、それぞれの目的に応じてbindlivedelegateなどのメソッドを使い分ける必要がありました。しかし、これらの使い分けが分かりにくかった上、構文もふぞろいで使いにくかったため、1.7で統一メソッドとしてonが提供されるようになったのです。

 jQuery 1.6以前を知っている方も、今後はbindlivedelegateなどの古いメソッドを利用すべきではありません(そもそもliveメソッドは1.9以降で利用できなくなっています)。

 以下に、onメソッドとbindlivedelegateメソッドとの構文対応を示します。

jQuery 1.6以前の構文jQuery 1.7以上の構文
$(セレクター).bind(イベント名, リスナー) $(セレクター).on(イベント名, リスナー)
$(セレクター).live(イベント名, リスナー) $(document).on(イベント名, セレクター, リスナー)
$(セレクター).delegate(子セレクター, イベント名, リスナー) $(セレクター).on(イベント名, 子セレクター, リスナー)
新旧イベントメソッドの構文比較
処理対象:イベントリスナー カテゴリ:イベント
API:.on()|.bind()|.live()|.delegate() カテゴリ:Events(イベント) > Event Handler Attachment
API:jQuery()/$() カテゴリ:Core(コア)

※以下では、本稿の前後を合わせて5回分(第15回~第19回)のみ表示しています。
 連載の全タイトルを参照するには、[この記事の連載 INDEX]を参照してください。

jQuery逆引きリファレンス
15. イベントに応じて処理を実行するには?(イベントメソッド)

イベントの発生に応じて呼び出されるイベントリスナーをjQueryで実装するための基本的な方法を解説する。

jQuery逆引きリファレンス
16. イベントメソッドで提供されないイベントを処理するには?(on)

onメソッドを利用して、jQueryが標準で対応していないJavaScriptイベントにアクセスする方法を説明する。

jQuery逆引きリファレンス
17. 【現在、表示中】≫ 文書ツリー上に存在しない要素に対してイベントリスナーを追加するには?(on)

onメソッドを利用して、動的に新規追加された要素にイベントリスナーを設置する方法を解説。またjQuery 1.6以前のbind/live/delegateメソッドをonメソッドに置き換える方法も説明する。

jQuery逆引きリファレンス
18. イベントリスナーを呼び出す際にパラメーターを引き渡すには?(data)

イベントメソッドやonメソッドの呼び出し時に、任意のパラメーターを引き渡す方法を解説する。

jQuery逆引きリファレンス
19. マウスポインターが要素に出入りした時の処理を実装するには?(mouseover、mouseout、mouseenter、mouseleave、hover)

違いが分かりにくい「mouseover/mouseout」と「mouseenter/mouseleave」イベントの使い分け方法を解説。また、これらに関連する「hover」イベントメソッドについても説明する。

サイトからのお知らせ

Twitterでつぶやこう!