web-dev-qa-db-ja.com

jquery .live( 'click')vs .click()

.click(function {...});よりも.live('click', function {...});を使用したほうが良い状況があるかどうか疑問に思っています。

私が収集したライブオプションは、より良いオプションのようです。したがって、特に多くのコードが非同期にロードされる場合、プレーン.click()の代わりにほとんどすべての状況でそれを使用しています。

編集:この質問の別の部分。すべてのjavascriptを非同期でロードしている場合、.clickは、dom内のすべての要素を引き続きピックアップします。右?

58
kalpaitch

既に存在するオブジェクトにクリックハンドラーのみを明示的に割り当て、新しいオブジェクトを異なる方法で処理したい場合があります。しかし、より一般的には、ライブは常に機能するとは限りません。次のような連鎖jQueryステートメントでは機能しません。

_$(this).children().live('click',doSomething);
_

イベントがDOMツリーをバブルアップするため、セレクターが適切に機能する必要があります。

編集:誰かがこれを支持したので、明らかに人々はまだそれを見ています。 livebindは両方とも 非推奨 であることに注意してください。 .on() で両方を実行できます。IMOの方がはるかに明確な構文です。 bindを置き換えるには:

_$(selector).on('click', function () {
    ...
});
_

liveを置き換えるには:

_$(document).on('click', selector, function () {
    ...
});
_

$(document)を使用する代わりに、クリックを監視しているすべての要素を含むjQueryオブジェクトを使用できますが、呼び出すときに対応する要素が存在する必要があります。

135
Nathan MacInnes

注29/08/2017:liveは多くのバージョンで廃止され、v1.9で削除されました。delegate v3.0で廃止されました。どちらの場合も、代わりに on の委任署名を使用してください[以下も参照)。


liveは、DOMからドキュメントルートまでバブルされたときにイベントをキャプチャし、ソース要素を調べることで発生します。 clickは、要素自体のイベントをキャプチャすることにより発生します。したがって、liveを使用していて、先祖要素の1つがイベントを直接フックしている(そしてバブルし続けるのを防いでいる)場合、要素にイベントが表示されることはありません。通常、イベントに最も近い要素(クリックなど)が最初に取得されますが、liveイベントと非liveイベントの混在により、微妙に変化する可能性があります。

例えば:

jQuery(function($) {

  $('span').live('click', function() {
    display("<tt>live</tt> caught a click!");
  });

  $('#catcher').click(function() {
    display("Catcher caught a click and prevented <tt>live</tt> from seeing it.");
    return false;
  });

  function display(msg) {
    $("<p>").html(msg).appendTo(document.body);
  }

});
<div>
  <span>Click me</span>
  <span>or me</span>
  <span>or me</span>
  <div>
    <span>I'm two levels in</span>
    <span>so am I</span>
  </div>
  <div id='catcher'>
    <span>I'm two levels in AND my parent interferes with <tt>live</tt></span>
    <span>me too</span>
  </div>
</div>
<!-- Using an old version because `live` was removed in v1.9 -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js">
</script>

可能な場合は、 delegate over liveを使用することをお勧めします。これにより、スコープをより完全に制御できます。 delegateを使用して、バブリングイベントをキャプチャするルート要素を制御します(たとえば、liveは基本的にドキュメントルートをルートとして使用するdelegateです)。また、(可能な場合)delegateまたはliveが非委任、非ライブイベント処理と対話することを避けることをお勧めします。


数年後、ここではlivedelegateも使用しません。 onの委任署名を使用しますが、概念は同じです。イベントはonを呼び出す要素でフックされますが、子孫が指定されたセレクタに一致する場合にのみ起動されますイベント名の後:

jQuery(function($) {

  $(document).on('click', 'span', function() {
    display("<tt>live</tt> caught a click!");
  });

  $('#catcher').click(function() {
    display("Catcher caught a click and prevented <tt>live</tt> from seeing it.");
    return false;
  });

  function display(msg) {
    $("<p>").html(msg).appendTo(document.body);
  }

});
<div>
  <span>Click me</span>
  <span>or me</span>
  <span>or me</span>
  <div>
    <span>I'm two levels in</span>
    <span>so am I</span>
  </div>
  <div id='catcher'>
    <span>I'm two levels in AND my parent interferes with <tt>live</tt></span>
    <span>me too</span>
  </div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
12
T.J. Crowder

.clickに関連付けられるすべてのオブジェクトは、イベントを設定するときに存在する必要があります。

例:(擬似コードで)追加は$("body").append()のようにできます

append('<div id="foo" class="something">...</div>');
$("div.something").click(function(){...});
append('<div id="bar" class="something">...</div>');

クリックはfooでは機能しますが、バーでは機能しません

例2:

append('<div id="foo" class="something">...</div>');
$("div.something").live("click",function(){...});
append('<div id="bar" class="something">...</div>');

クリックはfooとbarの両方で機能します

.live( 'click' ...を使用すると、イベントの作成後にオブジェクトを動的に追加できますが、クリックイベントは引き続き機能します。

10
fmsf

「ライブ」は、コードを動的に生成するときに必要です。以下の例を見てください:

$("#div1").find('button').click(function() {
    $('<button />')
     .text('BUTTON')
     .appendTo('#div1')
})
$("#div2").find('button').live("click", function() {
    $('<button />')
     .text('BUTTON')
     .appendTo('#div2')
})
button {
  margin: 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.0/jquery.min.js"></script>
<div id="div1">
  <button>Click</button>
</div>
<div id="div2">
  <button>Live</button>
</div>

「ライブ」がなければ、クリックイベントは最初のボタンをクリックしたときにのみ発生し、「ライブ」ではクリックイベントは動的に生成されたボタンにも発生します

5
Mr. Black

要素を動的に追加しない場合は、常にclickを使用します。

liveは、イベントリスナをドキュメントルートに追加することで機能し、バブルイベントをリッスンします。代替手段は delegate です。これは同じように機能しますが、イベントハンドラーを指定された要素にバインドします。
この方法では、イベントはDOM全体をバブルアップさせることなく、より早くキャッ​​チされます。

4
Felix Kling

.live()は、最初のページのロード後に要素が追加される場合に使用されます。ページがロードされた後にAJAX呼び出しによって追加されるボタンがあるとします。この新しいボタンは.click()を使用してアクセスできないため、.live(を使用する必要があります'クリック')

3
dotty

「ライブ」は現在のセレクタに一致する将来の要素のイベントを処理するため、クリックしないように選択できます。現在の選択された要素のみを処理する必要があります。

また、「ライブ」よりも「クリック」を使用した方がわずかな効率があると思われます(証拠はありませんが)。

リー

1
Lee Atkinson

私が理解している重要な違いから、live()は作業中のセレクターに一致する新しいDOM要素に目を光らせているのに対して、click()(またはbind( 'click'))はイベントフックをアタッチして終了します。

コードの多くが非同期にロードされることを考えると、live()を使用すると、多くのことが簡単になります。ロードするコードが正確にわからないが、どの種類の要素をリッスンしているのかがわかっている場合は、この関数を使用するのが最適です。

パフォーマンスの向上という点では、live()を使用する代わりにAJAXコールバック関数を実装してイベントフックを再バインドすることもできます。

var ajaxCallback = function(){
 $('*').unbind('click');
 $('.something').bind('click', someFunction);
 $('.somethingElse').bind('click', someOtherFunction);
}

イベントフックを適切に追跡し、この関数が適切なイベントを再バインドしていることを確認する必要があります。

追伸Ajaxメソッドの.get()、. post()、. load()、および.ajax()はすべて、コールバック関数を指定できます。

1
Joe Green

「ライブ」の使用は「jQuery 1.3」以上であることを忘れないでください

バージョン「jQuery 1.4.3」以降では「デリゲート」が使用されます

バージョン「jQuery 1.7 +」以上が「オン」で使用されている

$( selector ).live( events, data, handler ); // jQuery 1.3+
$( document ).delegate( selector, events, data, handler ); // jQuery 1.4.3+
$( document ).on( events, selector, data, handler ); // jQuery 1.7+

JQuery 1.7以降、.live()メソッドは非推奨になりました。

チェック http://api.jquery.com/live/

よろしく、フェルナンド

0
Fernando

コードを簡素化する必要がある場合、ほとんどの場合、ライブの方が優れています。最高のパフォーマンスを得る必要がある場合、デリゲートはライブよりも常に優れています。バインド(クリック)vsデリゲートはそれほど単純な質問ではありません(同様のアイテムがたくさんある場合は、デリゲートが優れています)。

0
oryol

T.J。Crowders answer に加えて、スニペットに新しい.on(...)ハンドラーを含むハンドラーをいくつか追加しました。これにより、どのイベントが非表示になっており、どのイベントが非表示になっているかを確認できます。

私が見つけたのは、.live()は非推奨であるだけでなく、jQuery 1.9.x以降で削除されたことです。しかし、他のもの、すなわち.
.click.delegate/.undelegateおよび.on/.off
まだあります。

また、このトピックに関する詳細な議論があることに注意してください ここStackoverflow

.liveに依存しているレガシーコードを修正する必要があるが、jQueryの新しいバージョン(> 1.8.3)を使用する必要がある場合は、次のスニペットで修正できます。

// fix if legacy code uses .live, but you want to user newer jQuery library
if (!$.fn.live) {
    // in this case .live does not exist, emulate .live by calling .on
    $.fn.live = function(events, handler) {
      $(this).on(events, null, {}, handler);
    };
}

T.J.のスクリプトの拡張である以下のスニペットの意図は、複数のハンドラーをバインドするとどうなるかを自分ですぐに試すことができることです。スニペットを実行して、下のテキストをクリックしてください。

jQuery(function($) {

  // .live connects function with all spans
  $('span').live('click', function() {
    display("<tt>live</tt> caught a click!");
  });

  // --- catcher1 events ---

  // .click connects function with id='catcher1'
  $('#catcher1').click(function() {
    display("Click Catcher1 caught a click and prevented <tt>live</tt> from seeing it.");
    return false;
  });

  // --- catcher2 events ---

  // .click connects function with id='catcher2'
  $('#catcher2').click(function() {
    display("Click Catcher2 caught a click and prevented <tt>live</tt>, <tt>delegate</tt> and <tt>on</tt> from seeing it.");
    return false;
  });

  // .delegate connects function with id='catcher2'
  $(document).delegate('#catcher2', 'click', function() {
    display("Delegate Catcher2 caught a click and prevented <tt>live</tt> from seeing it.");
    return false;
  });

  // .on connects function with id='catcher2'
  $(document).on('click', '#catcher2', {}, function() {
    display("On Catcher2 caught a click and prevented <tt>live</tt> from seeing it.");
    return false;
  });

  // --- catcher3 events ---

  // .delegate connects function with id='catcher3'
  $(document).delegate('#catcher3', 'click', function() {
    display("Delegate Catcher3 caught a click and <tt>live</tt> and <tt>on</tt> can see it.");
    return false;
  });

  // .on connects function with id='catcher3'
  $(document).on('click', '#catcher3', {}, function() {
    display("On Catcher3 caught a click and and <tt>live</tt> and <tt>delegate</tt> can see it.");
    return false;
  });

  function display(msg) {
    $("<p>").html(msg).appendTo(document.body);
  }

});
<!-- with JQuery 1.8.3 it still works, but .live was removed since 1.9.0 -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js">
</script>

<style>
span.frame {
    line-height: 170%; border-style: groove;
}
</style>

<div>
  <span class="frame">Click me</span>
  <span class="frame">or me</span>
  <span class="frame">or me</span>
  <div>
    <span class="frame">I'm two levels in</span>
    <span class="frame">so am I</span>
  </div>
  <div id='catcher1'>
    <span class="frame">#1 - I'm two levels in AND my parent interferes with <tt>live</tt></span>
    <span class="frame">me too</span>
  </div>
  <div id='catcher2'>
    <span class="frame">#2 - I'm two levels in AND my parent interferes with <tt>live</tt></span>
    <span class="frame">me too</span>
  </div>
  <div id='catcher3'>
    <span class="frame">#3 - I'm two levels in AND my parent interferes with <tt>live</tt></span>
    <span class="frame">me too</span>
  </div>
</div>
0
Matt