2011年6月16日木曜日

[jQuery] liveとdelegateの違いとevent.stopPropagaton()

例えばこのような構造のHTMLがあるとして

<html>
  <body>

    <ul>
      <li>...</li>
      <li>...</li>
    </ul>

  </body>
</html>
こんなイベントを追加してみます。
$(document).click(function () {
  console.log('document !!');
});

$('li').click(function () {
  console.log('li !!');
});
li要素をクリックしたとき、li要素のクリック・イベントは発生してほしいけど、documentのクリック・イベントは発生して欲しくない時はどうすればよいでしょうか

event.stopPropagaton()を使えば簡単に実現できます。
$('li').click(function (event) {
  event.stopPropagaton();
  console.log('li !!');
});


では、
clickメソッドの代わりにliveメソッドでイベントを登録する場合はどうでしょうか
$('li').live('click', function (event) {
  event.stopPropagaton();
  console.log('li !!');
});
これはドキュメントにも記載されている通り、狙い通りには機能しません
li要素のイベントとともにdocumentのイベントも発生してしまいます。



そういう時に delegateメソッド が使えます。
$('ul').delegate('li', 'click', function (event) {
  event.stopPropagaton();
  console.log('li !!');
});


liveメソッドは見かけ上指定されたセレクタにイベントがひもづいているように見えますが、デフォルトではdocument rootに登録されます。

delegateメソッドはこの登録先を独自に指定できるところがliveメソッド違います。


実は liveメソッドもcontext を利用して登録先を指定できます。
$('li', $('ul')[0]).live('click', function() {
  // Live handler called.
});
ただ、個人的にはこれはちょっと見通しが悪い書き方のような気がします。
$('ul').delegate('li', 'click', function (event) {
 
});
こっちのほうがすっきりしている印象があります。

0 件のコメント: