jQuery 1.7の on() off()について調べてみた

jQuery 1.7の on() off()について調べてみた

新しいチャリを手に入れたら歯車や金属のバーを眺めてニヤニヤするようになったminamiです。

11/3にjQueryの最新バージョン1.7がリリースされました。大小さまざまな機能追加がされましたが、その中でもかなり大きな「.on()」「.off()」というイベントAPIが追加されましたが、今までのイベントAPIとどう違うのかいまいちわからなかったので調べてみました。

「.on()」「.off()」の使いどころ

jQueryには今までのバージョンにも、「.bind()」「.live()」「.delegate()」といったイベントAPIがありました。今回追加された「.on()」「.off()」はそれら3つの機能をカバーしたメソッドになります。

「.bind()」「.live()」「.delegate()」については今後も利用できますが、「.on()」「.off()」の使用が推奨されていくようです。

どう違うの?

今までの3つのAPIも少しづつ違う機能が提供されていましたが、それらを「.on()」「.off()」で書き換えるにはどうすればよいかサンプルを作ってみました。

.bind()を書き換える

「.bind()」はセレクタに対してイベントを設定します。
イベントを削除するには「.unbind()」を使います。

//a要素をクリックするとアラートを表示
$('a').bind('click',function(){
	alert('クリックされました!');
});

//クリックイベントを削除
$('a').unbind('click');

「.on()」「.off()」を使って同じように書くと以下のようになります。

//a要素をクリックするとアラートを表示
$('a').on('click',function(){
	alert('クリックされました!');
});
//クリックイベントを削除
$('a').off('click');

「.bind()」「.unbind()」だったところが置き換わっただけですね。わかりやすいです。

.live()を書き換える

「.live()」はセレクタにイベントを設定しますが、「.bind()」と違う点は、「.bind()」が実行される時点で存在するセレクタの要素に対してイベントを設定するのに対し、「.live()」では将来的に追加されるセレクタにマッチする要素にもイベントが適用されるというところです。

//a要素をクリックすると後ろに自分のクローンを挿入
$('a').live('click',function(){
	$(this).clone(false).insertAfter(this);
});

このサンプルではクリックで新たに増えたa要素にもクリックイベントが適用されます。.live()で設定したイベントを削除するには「.die()」を使います。

//クリックイベントを削除
$('a').die('click');

「.on()」「.off()」を使って同じように書くと以下のようになります。

//a要素をクリックすると後ろに自分のクローンを挿入
$(document).on('click','a',function(){
	$(this).clone(false).insertAfter(this);
});

//クリックイベントを削除
$(document).off('click','a');

「.live()」と同じ効果を持たせるには、document要素に対して「.on()」を実行し、引数にセレクタを渡します。
なぜこんな書き方に?と思いましたが、実は「.live()」は内部的にはまず、(document)に対してイベントを設定し、イベント発生源からバブリングで上がってきた要素がCSSセレクタと一致するかを見て設定したイベントを実行している、とのこと。
一見?なのですが、実行されている対象がわかりやすい書き方になったということでしょうか。

ちなみに以前、「.live()」が.each()内の$(this)に対して効かない、 という現象でハマったことがあるのですが、このようなしくみであれば当然ですね・・・

↓ハマった際お世話になった記事です。

.delegate()を書き換える

「.delegate()」は「.live()」に似ていますがすこし違います。
「.live()」が内部的にはまず(document)内のセレクタに該当する要素全てに作用するのに対し、「.delegate()」は第1引数にjQueryセレクタを設定することができ、設定したセレクタ内の要素のみにイベントを設定できます。

//id="test" 内のaをクリックすると後ろに自分のクローンを挿入
$('#test').delegate('a','click',function(){
	$(this).clone(false).insertAfter(this);
});

//イベントを削除
$('#test').undelegate('a','click');

「.on()」「.off()」を使って同じように書くと以下のようになります。

//id="test" 内のaをクリックすると後ろに自分のクローンを挿入
$('#test').on('click','a',function(){
	$(this).clone(false).insertAfter(this);
});

//クリックイベントを削除
$('#test').off('click','a');

まとめ

若干ややこしかったですが、「.live()」がdocumentに対して実行されているということがわかると、「.on()」「.off()」にまとめられたほうがスッキリするな、と思いました。

こちらの記事ではそれぞれのイベントAPIの詳しいしくみや、.delegate()のほうが.live()より優れている点などを解説しています。

細かい部分の仕様の定義などは少しあいまいなところもあるので、何か間違っている点などあれば教えてください!

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

この記事を読んだ人にオススメ