Kokudoriing

技術系与太話ブログ

jQuery.fn.bind, unbind, live, die, delegate, undelegate を使ってはいけない

$.fn.on, $.fn.off を使いましょう。
on と off はそれらを完全に置き換えるAPI
タイピングも少なく済むのでありがたいですね。
on と off についてはこちらあたりで詳しく解説されてます。

でも既存のAPIでうまく行ってるのに on と off を使うメリットってなんなのさ。

一番は直感的になったこと。特に live と delegate の差とか。
昔から live 使うな delegate 使えと言う記事がありました。
(live はバージョン1.8.1現在で公式にDeprecatedです。)
live は $(document).on('event', 'selector', handler) なので、document 以下から find してるわけですね。
一方 delegate は $('selector').on('event', 'selector', handler) なのでセレクタ内で find してるわけです。
当たり前ですが殆どの場合 document 以下の要素を探すほうがコストがでかいです。
これも $(document) にバインドしてるからだと考えれば直感的になりましたねと。

次はもうちょっとぶっ飛んだ話。

今までは bind, unbind, live, die, delegate, undelegate と同じようなメソッドが6個もありました。
しかし on, off はたったの2個。
これがすごく嬉しい場面として、jQuery Event のラッパオブジェクト。

(function($, undefined) {
  var event = $({}),
    wrapper = {
      on: function() {
        return $.fn.on.call(event, arguments);
      },
      off: function() {
        return $.fn.off.call(event, arguments);
      },
      trigger: function() {
        return $.fn.trigger.call(event, arguments);
      },
    };
}).call(this, jQuery);

これで wrapper.on や wrapper.trigger とあたかもjQueryオブジェクトのような振る舞い。
それでおいてその他の不必要なAPIを継承していないのでメモリにもAPI構造にも易しい。

これが on, off 前は6個書かないとダメだったねというだけのお話。

ちなみにこれを一つ(多分Factory Methodにしてインスタンス化するべきだろうけども)作っておけば
$.extend や Object.create やらで簡単に再利用可能。

注意したいのはFactory Method化する時に event も内部クロージャに置いて毎回作成すること。
そうしないと wrapper を継承したすべてのオブジェクト間でイベントが共有されてしまう。

まぁどっちにしろ on, off 以外はいずれ非推奨になり統合されるであろう運命にあると思いますので使わないに越したことはないです。