web-dev-qa-db-ja.com

動的HTMLのロード後にクリックイベントを追加するためのjQueryの.live()と.on()メソッド

私はjQuery v.1.7.1を使用しています。ここでは.live()メソッドは明らかに推奨されていません。

私が抱えている問題は、動的にHTMLを要素にロードするときに、

$('#parent').load("http://..."); 

後でクリックイベントを追加しようとしても、これらの方法のいずれかを使用してイベントを登録することはできません。

$('#parent').click(function() ...); 

または

// according to documentation this should be used instead of .live()
$('#child').on('click', function() ...); 

この機能を実現するための正しい方法は何ですか?それは私にとっては.live()でしか動作しないようですが、そのメソッドを使うべきではありません。 #childは動的に読み込まれる要素です。

ありがとう。

203
Sean Thoman

動的にロードされる要素に対してクリックハンドラを機能させる場合は、(動的にロードされない)親オブジェクトにイベントハンドラを設定し、動的オブジェクトに一致するセレクタを次のように指定します。

$('#parent').on("click", "#child", function() {});

イベントハンドラは#parentオブジェクトにアタッチされ、クリックイベントが#childから発生したオブジェクトにバブルアップするたびにクリックハンドラが起動されます。これは、委任イベント処理と呼ばれます(イベント処理は親オブジェクトに委任されます)。

#parentオブジェクトがまだ存在していなくても#childオブジェクトにイベントをアタッチすることができますが、後でそれが存在してクリックされると、clickイベントは#parentオブジェクトまでバブルされるので、それはそれを見るでしょう#childから発生し、#childをクリックしてイベントを発生させるためのイベントハンドラがあります。

585
jfriend00

これを試して:

$('#parent').on('click', '#child', function() {
    // Code
});

$.on() のドキュメントから:

イベントハンドラは現在選択されている要素にのみバインドされます。コードが.on()を呼び出すときに、それらはページに存在しなければなりません。

あなたが$.on()を呼び出すとき、あなたの#child要素は存在しません、それでイベントは縛られません($.live()とは異なり)。 #parent、しかし、存在するので、それにイベントをバインドすることは問題ありません。

上記のコードの2番目の引数は、イベントが#parentから#childまでバブルアップした場合にのみトリガーされる「フィルター」として機能します。

32
Bojangles

$(document).on('click', '#selector', function() { /* do stuff */ });

編集:私はこれがどのように機能するかについてもう少し情報を提供しています、なぜなら...言葉。この例では、文書全体にリスナーを配置しています。

#selectorと一致する要素にclickを指定すると、そのイベントはメイン文書にバブルアップします - 他のevent.stopPropagation()メソッドを呼び出すリスナーがいない限り - これは親要素へのイベントのバブリングの先頭に立つでしょう。

特定の要素または要素のセットにバインドする代わりに、指定されたセレクターに一致する要素からのイベントを待機しています。つまり、動的に追加された要素だけでなく現在の要素にも自動的に一致するリスナーを一度に1つ作成できます。

これは、パフォーマンスやメモリ使用率(大規模アプリケーションで)など、いくつかの理由からスマートです。

20
L422Y

1.7の.live()と同等のものはこのようになります。

$(document).on('click', '#child', function() ...); 

基本的に、クリックイベントについてドキュメントを監視し、#childのためにそれらをフィルタリングします。

11
Jared

私は答えがもう少し遅れているのを知っています、しかし私は.live()メソッドのためのpolyfillを作成しました。私はjQuery 1.11でそれをテストしました、そしてそれはかなりうまくいくようです。可能な限り.on()メソッドを実装することになっていますが、大規模なプロジェクトでは、何らかの理由ですべての.live()呼び出しを同等の.on()呼び出しに変換することは不可能です。作業:

if(jQuery && !jQuery.fn.live) {
    jQuery.fn.live = function(evt, func) {
        $('body').on(evt, this.selector, func);
    }
}

JQueryをロードした後で、live()を呼び出す前にそれを含めるだけです。

9
NSV

.on()はjQueryバージョン1.7以上用です。あなたがより古いバージョンを持っているならば、これを使ってください:

$("#SomeId").live("click",function(){
    //do stuff;
});
5
Matt Cashatt

私は自分のプロジェクトで 'live'を使用しましたが、私の友人の一人は私がliveの代わりに 'on'を使用することを勧めました。そして、私がそれを使用しようとしたとき、私はあなたが持っていたような問題を経験しました。

私のページで私はボタンのテーブルの行と多くのDOMのものを動的に作成しています。しかし、私は魔法で使用すると姿を消した。

子供のようにそれを使用するような他のソリューションは、クリックするたびに毎回あなたの関数を呼び出すだけです。しかし、私はそれが再び起こるようにする方法を見つけますそしてここに解決策があります。

あなたのコードを書いてください:

function caller(){
    $('.ObjectYouWntToCall').on("click", function() {...magic...});
}

Caller()を呼び出します。このようにページにオブジェクトを作成した後。

$('<dom class="ObjectYouWntToCall">bla... bla...<dom>').appendTo("#whereeveryouwant");
caller();

このようにして、あなたの関数は、ページをクリックするたびに呼び出されるとは限らないときに呼び出されます。

3
Coderx07