以下斜め読んだ内容

pseudo translation of useful posts, book reviews, remarks,etc. twitter: feeddict

Jordan Boesch「jQuery1.4.2の.delegate(),.undelegate()の使い方」

Learning jQueryの2010.3.5の記事

Using Delegate and Undelegate in jQuery 1.4.2

Event Delegation with jQuery」(斜め読み内容)と似たテーマで書いてる。

以下斜め読んだ内容
  • .live()は色々議論のあるメソッド
  • .live()の問題点
    • 外見は他のメソッドチェーンで使うメソッドなのに見えにくい制約多い
    • traverse系と一緒に使えないので、メソッドチェーンにつなげない。
      • 最初にセットしないといけない
    • ネイティブのDOMオブジェクトを渡したjqueryオブジェクトでは動かない
// 動かない
$('ul').find('li').next().live('click', function(){});
// 動かない
$('ul').parent().nextAll().live('click', function(){});
//動かない
$(document.body).live('click', function(){});
  • .live()は問題があるがシンタックスはいじれない
    • 互換性
    • jqueryチームは、.live()の問題点を解決するためにメソッド追加した
      • それが、.delegate()と.undelegate()
  • .delegate()のいいとこ
    • contextの指定がスマート
    • .live()でも出来るが、.delegate()の方がスマート
  • .ldelegate()の制約
    • .bind()のときにはイベント/ハンドラーのセットを同時にセットできるが、.delegate()はできない
//.bind()の例:動く。
//.bind()でこの書き方できるようになったのは、1.4移行
$('ul li').bind({
  click: function(e){
 // Something on click
  },
  mouseover: function(e){
 // Something on mouse over
  }
});
//.delegate()の例:動かない
$('ul').delegate('li', {
  click: function(e){
 // Something on click
  },
  mouseover: function(e){
 // Something on mouse over
  }
});
  • .delegate()でもイベント/ハンドラのセットを同時に渡したいとき
    • プラン1:パッチを当てる
      • 上の.delegate()のコードを動くようしたい人向けにRobert Katicがパッチ書いてる
      • gist: 310747 - GitHub
    • プラン2:パッチ抜きでやるやり方。
      • イベント/関数という対のハッシュを作る
      • それをハンドラに仕込み、発火したイベントをキーに、call()を使って実行したい関数を呼び出す。
var customObjMap = {
  click : function(e){
 // Something on click
  },
  mouseover : function(e){
 // Something on mouse over
  }
};
$('ol').delegate('li', 'click mouseover', function(e){
  if($.isFunction(customObjMap[e.type])){//一応、.isFunction()使って、イベント名をキーに指定された値が関数であるかをチェック
 customObjMap[e.type].call(this, e);//call()を使って関数呼び出してevent target=thisに実行
  }
});
  • 他にもあった.delegata()の注意点
    • 特定イベント(mouseenter/mouseleave)でおかしかったけど、治ってた
  • コメント欄
    • お手軽な.click()よりも.live()/delegata()がいいところ
      • ajaxなどでノード更新された場合、clickだともう一回更新された要素に.click()を実行しないといけない
      • .live()/.delegata()ならそういう心配なし。context内の更新であれば自動的に捕捉される。