jQuery逆引きリファレンス
文書ツリー上に存在しない要素に対してイベントリスナーを追加するには?(on)
onメソッドを利用して、動的に新規追加された要素にイベントリスナーを設置する方法を解説。またjQuery 1.6以前のbind/live/delegateメソッドをonメソッドに置き換える方法も説明する。
onメソッドを利用することで、現時点では文書ツリー上に存在しない要素に対しても、イベントリスナーを設置できます。例えば、以下はボタンをクリックするたびに、ボタン自身が増殖していく例です。
<!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
メソッドの以下の構文を利用します。
[構文]onメソッド
$('親セレクター').on('イベント名', '子セレクター', function(e) {
……イベント発生時の処理……
})
これによって、「親セレクター配下の子セレクターで示された要素に対して、イベントリスナーを設置する」という意味になります。上のサンプルでも、$()
関数には、ボタンそのものではなく、ボタンの上位の<div>
要素が渡されていることを確認してください。イベントリスナーが対象の要素そのものではなく、コンテナー要素(親要素)によって管理されるので、配下の子要素が増減しても、そのイベントを監視できるわけです。
別稿で示したon
メソッドと、今回のものとの違いを図示すると次のようになります。
もしも(<div id="parent">
要素ではなく)ページ全体の<button class="btn">
要素をイベント監視の対象としたいならば、$(document)
に対してイベントリスナーを設置してください。これは次のコードのようになります。
$(document).on(
'click',
'.btn',
function() {
$('<button class="btn">プラス</button>')
.appendTo('#parent');
}
);
|
この構文には、もうひとつ、パフォーマンス上のメリットもあります。というのも、先ほどの図を見ても分かるように、前回の書き方では1つ1つの要素に対してイベントリスナーを設置していました。しかし、この構文では、子要素の数にかかわらず、イベントリスナーそのものはコンテナー要素1つに対して設置されるだけです。
その性質上、特に何十、何百にも及ぶ要素をイベント監視の対象とするケースでは*1、本稿の構文を利用することで、リスナー登録のオーバーヘッドを軽減できます。
- *1 例えば行数、セル数の多いテーブルにリスナーを登録するようなケースです。
補足:jQuery 1.6以前のメソッド
on
メソッドは、jQuery 1.7以上で追加された比較的新しいメソッドです。jQuery 1.6以前では、それぞれの目的に応じてbind
/live
/delegate
などのメソッドを使い分ける必要がありました。しかし、これらの使い分けが分かりにくかった上、構文もふぞろいで使いにくかったため、1.7で統一メソッドとしてon
が提供されるようになったのです。
jQuery 1.6以前を知っている方も、今後はbind
/live
/delegate
などの古いメソッドを利用すべきではありません(そもそもlive
メソッドは1.9以降で利用できなくなっています)。
以下に、on
メソッドとbind
/live
/delegate
メソッドとの構文対応を示します。
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]を参照してください。
17. 【現在、表示中】≫ 文書ツリー上に存在しない要素に対してイベントリスナーを追加するには?(on)
onメソッドを利用して、動的に新規追加された要素にイベントリスナーを設置する方法を解説。またjQuery 1.6以前のbind/live/delegateメソッドをonメソッドに置き換える方法も説明する。
19. マウスポインターが要素に出入りした時の処理を実装するには?(mouseover、mouseout、mouseenter、mouseleave、hover)
違いが分かりにくい「mouseover/mouseout」と「mouseenter/mouseleave」イベントの使い分け方法を解説。また、これらに関連する「hover」イベントメソッドについても説明する。