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()のときにはイベント/ハンドラーのセットを同時にセットできるが、.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()を使って実行したい関数を呼び出す。
- プラン1:パッチを当てる
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内の更新であれば自動的に捕捉される。
- お手軽な.click()よりも.live()/delegata()がいいところ