jQuery .bind() .live() .delegate() .on() .off()メソッドの違いと連絡
9254 ワード
.bind()
複数行の複数列のテーブルがあると仮定すると、各セルをクリックしてコンテンツに関する詳細な情報(プロンプトバーなど)を表示できます.これにより、各セルにclickイベントをバインドできます.
問題は、テーブルにクリックイベントをバインドする10列500行がある場合、5000個のセルを検索および遍歴するとスクリプトの実行速度が著しく遅くなり、5000個のtd要素と対応するイベントハンドラを保存するとメモリが大量に消費されます(ドアの前に立って宅配便を待つように).
上記の例に基づいて、簡単なアルバムアプリケーションを実現したい場合は、各ページに50枚の写真のサムネイル(50セル)しか表示されず、ユーザーは「xページ目」(または「次ページ」)リンクをクリックしてAjaxを通じてサーバから50枚の写真を動的にロードすることができます.この場合、使用するようである.bind()メソッドは、50個のセルバインドイベントを受け入れることができます.
事実はそうではない.使用するbind()メソッドは、最初のページの50個のセルにクリックイベントをバインドするだけで、動的にロードされた後続のページのセルにはこのクリックイベントはありません.言い換えればbind()は、呼び出されたときにすでに存在する要素バインドイベントのみを与えることができ、将来追加される要素バインドイベント(新しく来た従業員のように宅配便を受け取ることができない)を与えることはできません.
イベント依頼は上記の2つの問題を解決することができる.具体的には、jQuery 1.3で追加するものであればよい.live()メソッド代替.bind()メソッド:
ここのlive()メソッドはclickイベントを$(document)オブジェクトにバインドします(ただし、これはコードからは反映されません.これも.live()メソッドが非難されている重要な原因の一つです.後で詳しく説明します).また、$(document)に1回(50回ではなく、5000回ではありません)バインドするだけで、後続のダイナミックにロードされた写真セルのクリックイベントを処理できます.任意のイベントを受信すると、$(document)オブジェクトはイベントタイプとイベントターゲットをチェックし、clickイベントでイベントターゲットがtdである場合は、それに委任されたプロセッサを実行します.
.live()
今まで、すべてが完璧だったようだ.残念なことに、事実はそうではない.なぜならlive()の方法は完璧ではありません.以下の主な欠点があります.
$()関数は、現在のページのすべてのtd要素を見つけてjQueryオブジェクトを作成しますが、イベントターゲットを確認するときにこのtd要素の集合ではなく、セレクタ式とeventを使用します.targetまたはその祖先要素を比較するため、このjQueryオブジェクトを生成すると不要なオーバーヘッドが発生します.
デフォルトでは、イベントは$(document)要素にバインドされます.DOMネスト構造が深い場合、イベントバブルは多くの祖先要素を通過するとパフォーマンスが低下します.
直接選択する要素の後ろにしか置けず、接尾辞のDOM遍歴方法の後ろでは使用できない、すなわち$("#info_table td").live...いいですが、$("#info_table").find("td").live...いけません
td要素を収集してjQueryオブジェクトを作成しますが、実際に操作されているのは$(document)オブジェクトで、わかりにくいです.
解決の道
不要なjQueryオブジェクトの生成を避けるために、「早依頼」というhack、すなわち$(document)を用いることができる.ready()メソッド外部呼び出しlive():
ここで、(function($){...})(jQuery)は「直ちに実行される匿名関数」であり、名前の競合を防ぐための閉パッケージを構成している.匿名関数の内部で、$パラメータはjQueryオブジェクトを参照します.この匿名関数はDOMが準備完了するまで実行されません.このhackを使用する場合、スクリプトはページのhead要素にリンクおよび(または)実行される必要があります.このタイミングを選んだのは、document要素がちょうど利用可能で、DOM全体がまだ生成されていないからです.スクリプトを終了したbodyラベルの前に置くと、DOMが完全に利用可能になったので意味がありません.
イベントバブルによる性能損失を回避するため、jQueryは1.4から使用をサポートする.Live()メソッドでは、コンテキストパラメータを使用します.
これにより、「受託者」はデフォルトの$(document)から$(「#info_table」)[0]に変わり、泡立ちの旅を節約します.でも、と.Live()で共通に使用されるコンテキストパラメータは別々のDOM要素でなければならないので、ここでコンテキストオブジェクトを指定する際に使用されるのは$("#info_table")[0]、すなわち配列のインデックスオペレータを使用して取得されるDOM要素である.
.delegate()
前述ように、シングルを突破するために.Bind()メソッドの限界,イベント依頼の実現,jQuery 1.3が導入された.live()メソッド.その後、「イベント伝播チェーン」が長すぎる問題を解決するために、jQuery 1.4はまた支持する.Live()メソッドはコンテキストオブジェクトを指定します.一方、無意味に要素集合を生成する問題を解決するために、jQuery 1.4.2はいっそ新しい方法を直接導入した.delegate().
使用するdelegate()は、前の例では次のように書くことができます.
使用するdelegate()には、.live()メソッドの次のような利点があります.
ターゲット要素セレクタ(「td」)、イベント(「click」)およびプロセッサを直接「ドラッグ先」$(「#info_table」)にバインドし、要素の追加収集、イベント伝播経路の短縮、意味の明確化を行わない.
接尾辞のDOM遍歴メソッドの後に呼び出すことをサポートする、すなわち$(「table」)をサポートする.find("#info").delegate...,正確な制御をサポートする.
表示,.delegate()法は比較的完璧な解決策である.ただし、DOMの構造が簡単な場合には、使用することもできる.live().
ヒント:イベント委任を使用する場合、ターゲット要素に登録する他のイベントハンドラが使用する.stopPropagation()はイベントの伝播を阻止し,イベント依頼は失効する.
jQuery 1.7 Beta 1の発版説明による、jQuery 1.7は解決のためである.bind()、.live()と.delegate()の併存による不一致の問題は、新しいイベントメソッドのペアを追加する.on()と.off():
.on()
on(events,[selector],[data],fn)events:「click」または「keydown.myPlugin」など、1つ以上のイベントタイプとオプションのネーミングスペース.selector:フィルタのトリガイベントに使用されるセレクタ文字列のセレクタ要素の子孫.セレクタがnullまたは省略の場合、選択した要素に達すると、イベントは常にトリガーされます.Data:イベントがトリガーされたときにeventを渡す.dataはイベント処理関数に与えます.fn:イベントがトリガーされたときに実行される関数.false値は関数の略記をしてfalseを返すこともできます.bind()を置き換える2番目のパラメータ'selector'がnullの場合、on()とbind()は実は使い方にほとんど違いがないので、on()はbind()より1つだけオプションの'selector'パラメータが増えていると考えられますので、on()はbind()を置き換えてlive()を置き換えるのに便利です1.4までlive()が大好きだと信じていましたが、イベントを現在および後で追加する要素にバインドできるので、1.4以降でdelegate()も同様のことができます.live()の原理は簡単で,documentによるイベント委任であるため,on()を用いてdocumentにイベントをバインドすることでlive()のような効果を達成することもできる.live()書き方$('#list li').live('click', '#list li', function() {//function code here. }); on()書き方$(document).on('click', '#list li', function() {//function code here. }); ここで重要なのは2番目のパラメータ'selector'が機能していることです.選択した要素の子孫要素だけがイベントをトリガーするフィルタです.置換delegate()delegate()は1.4に導入され、祖先要素によって子孫要素を委任するイベントバインド問題を代理することを目的とし、live()の利点とある程度類似している.ただしlive()はdocument要素によって委任され、delegateは任意の祖先ノードであってもよい.on()を用いてエージェントの書き方がdelegate()とほぼ一致する.delegate()の書き方$('#list').delegate('li', 'click', function() {//function code here. }); on()書き方$('#list').on('click', 'li', function() {//function code here. }); 1番目と2番目のパラメータの順序が逆になっているようで、他の基本は同じです.jQueryがon()を出した目的をまとめると2つありますが、1つはインターフェースを統一するため、2つは性能を向上させるため、これからbind()、live()、delegateをon()で置き換えましょう.特にライブ()は使わないでください.もう推奨されていないリストにあるので、いつでもやられます.一度だけイベントをバインドするなら、one()を使いましょう.これは変わりません.
off()メソッドは、通常、on()メソッドで追加されたイベントハンドラを削除するために使用される.
複数行の複数列のテーブルがあると仮定すると、各セルをクリックしてコンテンツに関する詳細な情報(プロンプトバーなど)を表示できます.これにより、各セルにclickイベントをバインドできます.
$("info_table td").bind("click", function(){/* */});
問題は、テーブルにクリックイベントをバインドする10列500行がある場合、5000個のセルを検索および遍歴するとスクリプトの実行速度が著しく遅くなり、5000個のtd要素と対応するイベントハンドラを保存するとメモリが大量に消費されます(ドアの前に立って宅配便を待つように).
上記の例に基づいて、簡単なアルバムアプリケーションを実現したい場合は、各ページに50枚の写真のサムネイル(50セル)しか表示されず、ユーザーは「xページ目」(または「次ページ」)リンクをクリックしてAjaxを通じてサーバから50枚の写真を動的にロードすることができます.この場合、使用するようである.bind()メソッドは、50個のセルバインドイベントを受け入れることができます.
事実はそうではない.使用するbind()メソッドは、最初のページの50個のセルにクリックイベントをバインドするだけで、動的にロードされた後続のページのセルにはこのクリックイベントはありません.言い換えればbind()は、呼び出されたときにすでに存在する要素バインドイベントのみを与えることができ、将来追加される要素バインドイベント(新しく来た従業員のように宅配便を受け取ることができない)を与えることはできません.
イベント依頼は上記の2つの問題を解決することができる.具体的には、jQuery 1.3で追加するものであればよい.live()メソッド代替.bind()メソッド:
$("#info_table td").live("click",function(){/* */});
ここのlive()メソッドはclickイベントを$(document)オブジェクトにバインドします(ただし、これはコードからは反映されません.これも.live()メソッドが非難されている重要な原因の一つです.後で詳しく説明します).また、$(document)に1回(50回ではなく、5000回ではありません)バインドするだけで、後続のダイナミックにロードされた写真セルのクリックイベントを処理できます.任意のイベントを受信すると、$(document)オブジェクトはイベントタイプとイベントターゲットをチェックし、clickイベントでイベントターゲットがtdである場合は、それに委任されたプロセッサを実行します.
.live()
今まで、すべてが完璧だったようだ.残念なことに、事実はそうではない.なぜならlive()の方法は完璧ではありません.以下の主な欠点があります.
$()関数は、現在のページのすべてのtd要素を見つけてjQueryオブジェクトを作成しますが、イベントターゲットを確認するときにこのtd要素の集合ではなく、セレクタ式とeventを使用します.targetまたはその祖先要素を比較するため、このjQueryオブジェクトを生成すると不要なオーバーヘッドが発生します.
デフォルトでは、イベントは$(document)要素にバインドされます.DOMネスト構造が深い場合、イベントバブルは多くの祖先要素を通過するとパフォーマンスが低下します.
直接選択する要素の後ろにしか置けず、接尾辞のDOM遍歴方法の後ろでは使用できない、すなわち$("#info_table td").live...いいですが、$("#info_table").find("td").live...いけません
td要素を収集してjQueryオブジェクトを作成しますが、実際に操作されているのは$(document)オブジェクトで、わかりにくいです.
解決の道
不要なjQueryオブジェクトの生成を避けるために、「早依頼」というhack、すなわち$(document)を用いることができる.ready()メソッド外部呼び出しlive():
(function($){ $("#info_table td").live("click",function(){/* */}); })(jQuery);
ここで、(function($){...})(jQuery)は「直ちに実行される匿名関数」であり、名前の競合を防ぐための閉パッケージを構成している.匿名関数の内部で、$パラメータはjQueryオブジェクトを参照します.この匿名関数はDOMが準備完了するまで実行されません.このhackを使用する場合、スクリプトはページのhead要素にリンクおよび(または)実行される必要があります.このタイミングを選んだのは、document要素がちょうど利用可能で、DOM全体がまだ生成されていないからです.スクリプトを終了したbodyラベルの前に置くと、DOMが完全に利用可能になったので意味がありません.
イベントバブルによる性能損失を回避するため、jQueryは1.4から使用をサポートする.Live()メソッドでは、コンテキストパラメータを使用します.
$("td",$("#info_table")[0]).live("click",function(){/* */});
これにより、「受託者」はデフォルトの$(document)から$(「#info_table」)[0]に変わり、泡立ちの旅を節約します.でも、と.Live()で共通に使用されるコンテキストパラメータは別々のDOM要素でなければならないので、ここでコンテキストオブジェクトを指定する際に使用されるのは$("#info_table")[0]、すなわち配列のインデックスオペレータを使用して取得されるDOM要素である.
.delegate()
前述ように、シングルを突破するために.Bind()メソッドの限界,イベント依頼の実現,jQuery 1.3が導入された.live()メソッド.その後、「イベント伝播チェーン」が長すぎる問題を解決するために、jQuery 1.4はまた支持する.Live()メソッドはコンテキストオブジェクトを指定します.一方、無意味に要素集合を生成する問題を解決するために、jQuery 1.4.2はいっそ新しい方法を直接導入した.delegate().
使用するdelegate()は、前の例では次のように書くことができます.
$("#info_table").delegate("td","click",function(){/* */});
使用するdelegate()には、.live()メソッドの次のような利点があります.
ターゲット要素セレクタ(「td」)、イベント(「click」)およびプロセッサを直接「ドラッグ先」$(「#info_table」)にバインドし、要素の追加収集、イベント伝播経路の短縮、意味の明確化を行わない.
接尾辞のDOM遍歴メソッドの後に呼び出すことをサポートする、すなわち$(「table」)をサポートする.find("#info").delegate...,正確な制御をサポートする.
表示,.delegate()法は比較的完璧な解決策である.ただし、DOMの構造が簡単な場合には、使用することもできる.live().
ヒント:イベント委任を使用する場合、ターゲット要素に登録する他のイベントハンドラが使用する.stopPropagation()はイベントの伝播を阻止し,イベント依頼は失効する.
jQuery 1.7 Beta 1の発版説明による、jQuery 1.7は解決のためである.bind()、.live()と.delegate()の併存による不一致の問題は、新しいイベントメソッドのペアを追加する.on()と.off():
.on()
on(events,[selector],[data],fn)events:「click」または「keydown.myPlugin」など、1つ以上のイベントタイプとオプションのネーミングスペース.selector:フィルタのトリガイベントに使用されるセレクタ文字列のセレクタ要素の子孫.セレクタがnullまたは省略の場合、選択した要素に達すると、イベントは常にトリガーされます.Data:イベントがトリガーされたときにeventを渡す.dataはイベント処理関数に与えます.fn:イベントがトリガーされたときに実行される関数.false値は関数の略記をしてfalseを返すこともできます.bind()を置き換える2番目のパラメータ'selector'がnullの場合、on()とbind()は実は使い方にほとんど違いがないので、on()はbind()より1つだけオプションの'selector'パラメータが増えていると考えられますので、on()はbind()を置き換えてlive()を置き換えるのに便利です1.4までlive()が大好きだと信じていましたが、イベントを現在および後で追加する要素にバインドできるので、1.4以降でdelegate()も同様のことができます.live()の原理は簡単で,documentによるイベント委任であるため,on()を用いてdocumentにイベントをバインドすることでlive()のような効果を達成することもできる.live()書き方$('#list li').live('click', '#list li', function() {//function code here. }); on()書き方$(document).on('click', '#list li', function() {//function code here. }); ここで重要なのは2番目のパラメータ'selector'が機能していることです.選択した要素の子孫要素だけがイベントをトリガーするフィルタです.置換delegate()delegate()は1.4に導入され、祖先要素によって子孫要素を委任するイベントバインド問題を代理することを目的とし、live()の利点とある程度類似している.ただしlive()はdocument要素によって委任され、delegateは任意の祖先ノードであってもよい.on()を用いてエージェントの書き方がdelegate()とほぼ一致する.delegate()の書き方$('#list').delegate('li', 'click', function() {//function code here. }); on()書き方$('#list').on('click', 'li', function() {//function code here. }); 1番目と2番目のパラメータの順序が逆になっているようで、他の基本は同じです.jQueryがon()を出した目的をまとめると2つありますが、1つはインターフェースを統一するため、2つは性能を向上させるため、これからbind()、live()、delegateをon()で置き換えましょう.特にライブ()は使わないでください.もう推奨されていないリストにあるので、いつでもやられます.一度だけイベントをバインドするなら、one()を使いましょう.これは変わりません.
off()メソッドは、通常、on()メソッドで追加されたイベントハンドラを削除するために使用される.