jQueryの `click`、` bind`、 `live`、` delegate`、 `trigger`、` on`関数(例を含む)の違いは?


139

私はで各関数のドキュメントを読みました jQuery official websiteが、以下の関数の間にはそのような比較リストはありません。

$().click(fn)
$().bind('click',fn)
$().live('click',fn)
$().delegate(selector, 'click', fn)
$().trigger('click') // UPDATED
$().on('click', selector ,fn); // more UPDATED

参照リンクは避けてください。

上記のすべての機能はどのように正確に機能し、どの状況でどちらを優先する必要がありますか?

注:同じ機能またはメカニズムを持つ他の機能がある場合は、詳しく説明してください。

更新

$.trigger機能も見ました。上記の機能と同様に機能しますか?

その他の更新

v1.7.onで追加され、これは何らかの形で上記のすべての機能要件を一緒にカバーすると思います。


3
@I PHPのように、マニュアルでは答えられない質問や宿題の質問のように思えない人が投票することがあります。心配しないでください。他の人が有用だと思ったら投票します。
typeoneerror

@Typeoneerror-サポートをありがとう、私はすでにマニュアルを読んでいて、明確な違いが理解できないときはここに投稿します。
diEcho

3
@I PHPのように-少し整理するために質問を編集しました...これはよく尋ねられますが、このようにめったにないので、それは簡単に貴重なグーグル対応リソースになる可能性があります。このような何かのwiki風のエントリは非常に役立つことに同意します。特に.live().delegate()ほぼ毎日、完全に有効な質問の+1 に関して混乱が生じます。
Nick Craver

@Nick Craver編集ありがとうございます。どのように我々は上の質問を投稿しないことをどのmaunal /参照がありますSO。それは経験から来たもの
diEcho

@Iと同様にPHP -それは両方の少しですが、偉大なすべての周りのよくある質問SOここのためのがあります:meta.stackexchange.com/questions/7931フレージング/コメントのために、あなただけのための最良の方法に適合しているものを学ぶために始めます考えを伝え、コード>適切なキーワードを使用して適切にタグ付けすることで、説明を説明します。ここにいる時間が長ければ長いほど、多くのポスターが時間とともに改善していると思います。編集について.trigger()は、イベントハンドラーを呼び出すだけです。以下の回答に説明を追加します。
Nick Craver

回答:


162

これを読む前に、このイベントのリストを別のページプルアップしてください。API自体が非常に役立ちます。以下で説明するすべてのものは、このページから直接リンクされています

まず、.click(function)は文字通りのショートカットです.bind('click', function)。これらは同等です。次のように、ハンドラーを要素直接バインドするときに使用します。

$(document).click(function() {
  alert("You clicked somewhere in the page, it bubbled to document");
});

この要素が置換または破棄されると、このハンドラーは存在しなくなります。また、ハンドラーをアタッチするためにこのコードが実行されたときにそこなかった要素(たとえば、セレクターがそれを見つけた)は、ハンドラーを取得しません。

.live()そして、.delegate()同様に関連して、.delegate()実際に使用しています.live()彼らの両方がバブルにイベントをリッスン、内部的に。 これは新旧の要素で機能し、イベントを同じ方法でバブルします。新しい行やリストアイテムの追加など、要素が変更される可能性がある場合にこれらを使用します。ページにとどまり、どの時点でも置き換えられない親/共通の祖先がない場合は.live()、次のように使用します。

$(".clickAlert").live('click', function() {
  alert("A click happened");
});

ただし、置き換えられない場所に親要素がある場合(そのため、イベントハンドラーはバイバイではありません).delegate()、次のようにで処理する必要があります。

$("#commonParent").delegate('.clickAlert', 'click', function() {
  alert("A click happened, it was captured at #commonParent and this alert ran");
});

これはとほぼ同じよう.live()に機能しますが、イベントがキャプチャされてハンドラーが実行される前に、イベントがバブルする回数が少なくなります。これらの両方のもう1つの一般的な使用法は、要素でクラスが変更され、最初に使用したセレクターと一致しなくなったことです...これらのメソッドを使用すると、イベント時にセレクターが評価され、一致した場合、ハンドラーが実行されます。 .so要素がセレクターと一致しなくなったことが問題になり、実行されなくなります。では.click()ただし、イベントハンドラはDOM要素にバインドされた権利であり、それはそれを見つけるために使用されたものは何でもセレクタ一致していないという事実は関係ありません...イベントがバインドされ、その要素がなくなるまでそれが滞在しています、またはハンドラを介して削除され.unbind()ます。

まだのための別の一般的な使用.live()とは、.delegate()あるパフォーマンスが多数の要素を扱う場合は、クリックハンドラーを各要素に直接アタッチすると、コストと時間がかかります。これらのケースでは、単一のハンドラーをセットアップしてバブリングで処理を実行する方が経済的です。大きな違いが生じたこの質問を見てください。これはアプリケーションの良い例です。


トリガー -更新された質問

利用可能な2つの主要なイベントハンドラートリガー関数があり、それらはAPIの同じ「イベントハンドラーアタッチメント」カテゴリに分類されます。これらは.trigger()および.triggerHandler()です。 .trigger('eventName')には、一般的なイベントのショートカットがいくつか組み込まれています。次に例を示します。

$().click(fn); //binds an event handler to the click event
$().click();   //fires all click event handlers for this element, in order bound

これらのショートカットを含むリストをここで表示できます

違いについては.trigger()、イベントハンドラーをトリガーします(ただし、ほとんどの場合、デフォルトのアクションではありません。たとえば、クリックされたの適切な場所にカーソルを置きます<textarea>)。これにより、イベントハンドラーがバインドされた順序で(ネイティブイベントと同じように)発生し、ネイティブイベントアクションが発生し、DOMがバブルアップします。

.triggerHandler()通常は別の目的で使用します。ここでは、バインドされたハンドラーを起動しようとしていますが、フォームの送信など、ネイティブイベントを起動しません。これはDOMをバブルアップせず、チェーンもできません(そのイベントの最後にバインドされたイベントハンドラーが返すものは何でも返します)。たとえば、focusイベントをトリガーしたいが実際にはオブジェクトにフォーカスを当てたくない場合、バインドしたコード.focus(fn)を実行するだけで実行できますが、.trigger()実際には要素にフォーカスしてバブルアップします。

これが実際の例です:

$("form").submit(); //actually calling `.trigger('submit');`

これにより、jQuery検証プラグインなどの送信ハンドラが実行され、を送信しようとし<form>ます。しかし、あなたがいる場合だけで、それが経由フックアップなので、検証するために望んでいたsubmitイベントハンドラが、提出していない<form>、その後、あなたが使用することができ.triggerHandler('submit')、このように、:

$("form").triggerHandler('submit');

プラグインは、検証チェックに合格しなかった場合に爆撃によってハンドラーがフォームを送信するのを防ぎますが、このメソッドでは、それが何をするかは気にしません。中止したかどうかに関係なく、フォームを送信しようとしていないのに、フォームをトリガーして再検証を行い、他には何もしませんでした。(免責事項:.validate()プラグインにメソッドがあるため、これは余分な例ですが、意図の適切な例です)


非常に徹底しています。1つの小さな修正:triggerネイティブイベントを発生させません。ネイティブとは、fireEvent(IE)またはdispatchEvent(w3c)でシミュレートされたイベントを意味します。
クレセントフレッシュ

@Crescent-あいまいさが少なくなるように更新されました。フォームの送信やリンクの
追跡

@Nick私が読んでいるものlive()から、あなたのテイクはここで私に与えたものとは異なるようです:stackoverflow.com/questions/3981762 / ... 使用するときに「重量」はまだ問題live()ですか?
Yahel、2011

@yahelc-はい、もちろん...この答えは、イベントハンドラのオプションとその特定の目的を厳密に比較しています。重量コスト、初期バインディングの数、動的に何かを追加するかどうか、初期セレクターは、依然として有効な問題です。あなたのしているページの構造がない場合という大きなあなたが持っていないことを多くのイベントは、あなたしている罰金...重量の懸念は、あなたの構造の大きさ/深さやイベント(のの数に正比例します.live()呼び出しがリッスンするタイプ(例:)click生成されているタイプ。それぞれのセレクターを実行するため。
Nick Craver

1
jQuery 1.7では、live()は非推奨になり、$(document).on()が採用されました。
シンクロ

28

最初の2つは同等です。

// The following two statements do the same thing:
$("blah").click( function() { alert( "Click!" ); } );
$("blah").bind( "click", function() { alert( "Click!" ); } ); 

ただし、2つ目は、スペースで区切られた複数のイベント名を指定することにより、同時に複数のイベントにバインドするために使用できます。

$("blah").bind( "click mouseover mouseout", function() { alert( "Click! Or maybe mouse moved." ); } ); 

.liveこの方法は、より興味深いものです。次の例を検討してください。

<a class="myLink">A link!</a>
<a id="another">Another link!</a>

<script>
    $("a.myLink").click( function() { alert( 'Click!' ); } );

    $("a#another").addClass( "myLink" );
</script>

スクリプトの2行目が実行されると、2番目のリンクにも「myLink」というCSSクラスが含まれます。ただし、イベントがアタッチされたときにクラスがなかったため、イベントハンドラーはありません。

ここで、それを逆にしたいと考えてみましょう。「myLink」クラスのリンクがページのどこかに表示されるたびに、同じイベントハンドラーを自動的に設定します。これは、行またはセルを動的に追加するが、すべてが同じように動作するようなリストまたはテーブルがある場合に非常に一般的です。毎回新しいイベントハンドラーを割り当てるという面倒な作業に行く代わりに、次の.liveメソッドを使用できます。

<a class="myLink">A link!</a>
<a id="another">Another link!</a>

<script>
    $("a.myLink").live( "click", function() { alert( 'Click!' ); } );

    $("a#another").addClass( "myLink" );
</script>

この例では、2番目のリンクも「myLink」クラスを取得するとすぐにイベントハンドラーを取得します。マジック!:-)

もちろん、それはその通りではありません。どのような.live実際に行うことはありません指定された要素自体にはなく、HTMLの木(「ボディ」要素)の非常にルートにハンドラをアタッチです。DHTMLのイベントには、「バブリングアップ」というこの面白い機能があります。このことを考慮:

<div> <a> <b>text</b> </a> </div>

「テキスト」をクリックすると、最初に<b>要素が「クリック」イベントを取得します。その後、<a>要素は「クリック」イベントを取得します。その後、<div>要素は「クリック」イベントを取得します。など-<body>要素まで。そして、jQueryがイベントをキャッチし、そもそもイベントの原因となった要素に適用される「ライブ」ハンドラーがあるかどうかを確認します。きちんと!

そして最後に、.delegateメソッド。これは単に、指定されたセレクターに準拠する要素のすべての子を取り、それらに「ライブ」ハンドラーをアタッチします。見てください:

$("table").delegate( "td", "click", function() { alert( "Click!" ); } );

// Is equivalent to:
$("table").each( function() {
    $(this).find( "td" ).live( "click", function() { alert( "Click!" ); } );
} );

質問?


正確には、.live()バインドしdocumentません<body>:)ここでデモを表示できます。コンソールを引き上げて検査してください:jsfiddle.net/aJy2B
Nick Craver

3
このように説明する方が便利でした。:-)
フョードル・ソイキン

4
"body"部分は十分に公平ですが、 "<body>要素まで"は間違っており、イベントはそこを通過し続け、.live()ハンドラーが住んでいる場所ではなく、その上にありますdocument:)このデモ:jsfiddle.net/S2VBX
Nick Craver

8

jQuery 1.7以降、.live()メソッドは非推奨になりました。jQueryバージョン1.7未満を使用している場合は、.live()よりも.delegate()を使用することが公式に推奨されています。

.live()は.on()に置き換えられました。

詳細については、jQueryサイトに直接アクセスすることをお勧めしますが、ここに.on()メソッドの現在のバージョンがあります。

.on( events [, selector] [, data], handler(eventObject) )
.on( events-map [, selector] [, data] )

http://api.jquery.com/on/


2

$().click(fn)$().bind('click', fn)一見同じですが、$.bindバージョンは2つの理由でより強力です。

  1. $().bind()たとえば、1つのハンドラを複数のイベントに割り当てることができます$().bind('click keyup', fn)
  2. $().bind()名前空間付きイベントをサポート-要素がバインドされている特定のイベントハンドラーのみを削除(バインド解除)する場合の強力な機能- 名前付きイベントの詳細

ライブvsデリゲート:これはすでに他の返信で回答されています。


1

これは、APIを読むと役立つ場合があります。しかし、私は頭のてっぺんを知っているので、あなたは怠惰であり続けることができます(そうです!)。

$('#something').click(fn);
$('#something').bind('click',fn);

ここでは違いはありません(私が知っていることです)。 .click単に便利な/ヘルパーメソッドです.bind('click'

// even after this is called, all <a>s in
// <div class="dynamic_els"> will continue
// to be assigned these event handlers

$('div.dynamic_els a').live(‘click’,fn);

これは非常に異なります。これは、.live渡したセレクター(ここにはありません)にイベントを追加し、ノードが挿入/削除されるときにDOMを調べ続けるためです。

$('#some_element').delegate('td','click',fn);

これは、イベントハンドラーを割り当てる方法が異なるだけです。 .delegateDOMイベントのバブリングが中心です。基本的な原則は、すべてのイベントがルート要素に到達するまでDOMツリーを上方向にバブルすることです(documentまたはwindowまたは<html>または<body>、私は正確に思い出せません)。

どちらの方法でも、onclickハンドラーを<td>内部のすべてのにバインドします$('#some_element')(と言うこともできますが、セレクターを指定する必要があります$(document))。その子の1つがクリックされると、イベントがにバブルアップします<td>。次に、イベントのソース要素を抽出できます(jQueryが自動的に行います)。

これは、大量の要素があり、これらのイベントが通過するポイントが少数(または中央)しかない場合に役立ちます。これにより、ブラウザーの労力とメモリが節約され、これらのイベントハンドラーが少ないオブジェクトに統合されます。


1
.live() また、実際には、イベントバブリングオフ動作する.delegate()ためのラッパーです.live()それだけでコンテキストを追加し、要素に結合しています、よりもdocument泡をキャプチャします。バブリングハンドラーがどのように機能するかについての理解は少しずれていると思います(これが、jQuery 1.4で最もよく誤解されている側面だと思います)。ハンドラーはバインドした要素にのみ存在するため、呼び出し.delegate()た要素、またはdocumentの場合は.live()、イベントがそこにバブルすると、ターゲットをチェックして、セレクターと一致するかどうかを確認し、一致する場合は実行します。
Nick Craver
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.