読者です 読者をやめる 読者になる 読者になる

tacamy.blog

JavaScriptを勉強中の人のブログです。

jQuery の on() と off() を理解する

JavaScript jQuery

初心者向けの本とかだと、イベントを 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() で書いておいたほうがよさそうです。

参考サイト & 本 Thx♡