jQuery の on() と off() を理解する
初心者向けの本とかだと、イベントを jQuery オブジェクトの後に直接指定する、 $('.foo').click();
のような書き方で説明されている場合が多いけど、少し複雑なことをしようとするとそれだと困ることが出てきます。そんなときに便利なのが on() を使ったイベント設定です。
on() ひとつで bind() live() delegate() を表せる
jQuery 1.7 で、bind() live() delegate() がすべて on() に統合されたそうです。 つまり on() の書き方によって、3 パターンの使い方ができるということです。
.foo という要素をクリックしたら何かするという例で、イベントの設定と削除の方法をそれぞれ書いてみます。
bind()
$('.foo').bind('click', function(){...});
は $('.foo').click(function(){...});
と同じ意味で、ごく普通の基本的なイベント設定方法です。
その要素に対してイベントが発生したら何かするという感じ。
$('.foo').bind('click', function(){...}); $('.foo').unbind('click');
これを on() で書くとこうなります。
$('.foo').on('click', function(){...}); $('.foo').off('click');
一緒だったらわざわざ on() なんて使わずに click() でいいじゃんと思うかもしれませんが、このあとの話で on() にするメリットが出てきます。
delegate()
delegate() では、イベントを設定するのは親の要素に対して行います。delegate() の 1 番目の引数で、実際にクリックする要素 .foo を指定しますが、イベントが張り付いているのは親の .parent です。そして、 .parent の中にある .foo だけがクリックイベントの発生する対象となります。このように、親要素に対してイベントを設定することを、イベントデリゲートと言います。
最初に HTML が描画された後に、JavaScript によって要素を追加した場合、bind() でイベントを設定している場合は、後から追加された要素にはそのイベントが効きません。でも、delegate() の場合は、後から追加した要素にもちゃんとイベントを適用できます。
$('.parent').delegate('.foo', 'click', function(){...}); $('.parent').undelegate('.foo', 'click');
これを on() で書くとこうなります。
$('.parent').on('click', '.foo', function(){...}); $('.parent').off('click', '.foo');
live()
live() も delegate() と同じように、JavaScript を使って後から追加した要素に対してもイベントを設定できます。delegate() との違いは、イベントを設定する対象が document になります。でも、書き方は次のように .foo に対してイベントを設定しているように書きます。でも実際にイベントが設定されているのは document です。分かりにくい・・!
$('.foo').live('click', function(){...}); $('.foo').die('click');
これを on() で書くとこうなります。
$(document).on('click', '.foo', function(){...}); $(document).off('click', '.foo');
on() の書き方の方が、実際の挙動と見た目が一致していて分かりやすいです。あと、die() って名前、live() と対になってるのが分かりにくい気がする。英語できないからでしょうか・・。
ひとつの要素に複数のイベントを設定する方法
同じ処理をする複数のイベントを設定
on() のひとつ目の引数を、スペース区切りで複数指定することで、どのイベントが発生しても同じ処理をさせることができます。
$('.foo').on('click blur', function(){...});
別々の処理をする複数のイベントを設定
on() の中身を連想配列にすることで、イベントごとに異なる処理を記述できます。
$('.foo').on({ 'mouseenter': function(){...}, 'mouseleave': function(){...} });
イベントデリゲートで複数イベントを設定する
イベントの連想配列の後に、カンマで区切ってイベント対象の要素を指定します。
$('.parent').on({ 'mouseenter': function(){...}, 'mouseleave': function(){...} }, '.foo');
live() は廃止
live() と die() は jQuery 1.9 で廃止されました。 delegate() は今のところ廃止の予定はありませんが、on() が推奨なので、今から on() で書いておいたほうがよさそうです。