web-dev-qa-db-ja.com

JQueryを使って動的HTML要素にイベントを追加するにはどうすればよいですか?

クラス.myclassを持つすべての要素にイベントハンドラを添付するjQueryコードがあるとします。

例えば:

$(function(){
    $(".myclass").click( function() {
        // do something
    });
});

そして私のHTMLは次のようになるでしょう。

<a class="myclass" href="#">test1</a>
<a class="myclass" href="#">test2</a>
<a class="myclass" href="#">test3</a>

それは問題なく動作します。ただし、.myclass要素が将来的にページに書き込まれたかどうかを検討してください。

例えば:

<a id="anchor1" href="#">create link dynamically</a>
<script type="text/javascript">
$(function(){
    $("#anchor1").click( function() {
        $("#anchor1").append('<a class="myclass" href="#">test4</a>');
    });
});
</script>

この場合、ユーザーがtest4をクリックしたときにa#anchor1リンクが作成されます。

test4リンクは、たとえclass="myclass"を持っていても、それに関連するclick()ハンドラを持っていません。

基本的に、私はclick()ハンドラを一度書いて、それをページロード時に存在するコンテンツと AJAX/DHTML を通して後で持ち込まれるコンテンツの両方に適用させたいと思います。どうすればこれを解決できますか。

498
frankadelic

私は新しいjQueryリリースの変更を反映するために新しい答えを追加しています。 .live()メソッドはjQuery 1.7以降では非推奨です。

http://api.jquery.com/live/ から

JQuery 1.7以降、.live()メソッドは推奨されなくなりました。イベントハンドラを添付するには.on()を使用します。古いバージョンのjQueryのユーザーは、.live()よりも.delegate()を使用する必要があります。

JQuery 1.7以降の場合は、.on()を使用してイベントハンドラーを親要素にアタッチし、 'myclass'と組み合わせたセレクターを引数として渡すことができます。

http://api.jquery.com/on/ を参照してください。

だから代わりに...

$(".myclass").click( function() {
    // do something
});

あなたは書ける...

$('body').on('click', 'a.myclass', function() {
    // do something
});

これは、既に存在しているか、後で動的に追加されるかにかかわらず、本文に 'myclass'を含むすべてのタグに対して機能します。

ここではbodyタグを使用しています。この例では、静的な周囲のタグはそれほど静的ではありませんが、.onメソッド呼び出しが発生したときに存在する親タグはすべて機能します。たとえば、動的要素が追加されるリストのulタグは、次のようになります。

$('ul').on('click', 'li', function() {
    alert( $(this).text() );
});

Ulタグが存在する限り、これは機能します(まだli要素が存在する必要はありません)。

838
Sean

ときどき (トップ投票の回答) を実行するだけでは不十分です。

$('body').on('click', 'a.myclass', function() {
    // do something
});

注文イベントハンドラが起動されるため、これは問題になる可能性があります。あなたがこれをやっているのに気づいたが、それが扱われる順番のために問題を引き起こしています。あなたはいつでもそれを関数にラップすることができます。

例えば:

function RefreshSomeEventListener() {
    // Remove handler from existing elements
    $("#wrapper .specific-selector").off(); 

    // Re-add event handler for all matching elements
    $("#wrapper .specific-selector").on("click", function() {
        // Handle event.
    }
}

これは関数なので、このようにリスナーを設定するときはいつでも、通常は文書の準備ができた状態で呼び出します。

$(document).ready(function() {
    // Other ready commands / code

    // Call our function to setup initial listening
    RefreshSomeEventListener();
});

その後、動的に追加された要素を追加するたびに、そのメソッドをもう一度呼び出します。

function SomeMethodThatAddsElement() {
    // Some code / AJAX / whatever.. Adding element dynamically

    // Refresh our listener, so the new element is taken into account
    RefreshSomeEventListener();
}

うまくいけば、これは役立ちます!

よろしく、

73
Chandler Zwolle

JQuery 1.7以降、推奨されるメソッドは .on() および .off() です。

ショーンの答え は例を示しています。

今は廃止予定:

JQuery関数 .live() および .die() を使用してください。 jQuery 1.3.xで利用可能

ドキュメントから:

クリックするたびに各段落のテキストを警告ボックスに表示するには:

$("p").live("click", function(){
  alert( $(this).text() );
});

また、 livequery プラグインはこれを行い、より多くのイベントをサポートします。

36
Matt Brunell

DOMに大量のアンカーを追加する場合は、代わりにイベントの委任を調べてください。

これは簡単な例です:

$('#somecontainer').click(function(e) {   
  var $target = $(e.target);   
  if ($target.hasClass("myclass")) {
    // do something
  }
});
5
ScottE

現在および将来に一致するすべての要素のハンドラをイベント(clickなど)にバインドします。カスタムイベントをバインドすることもできます。

リンクテキスト

$(function(){
    $(".myclass").live("click", function() {
        // do something
    });
});
3
andres descalzo

それらが既にそのページにあるかどうかにかかわらず、あるいはそれらが将来のいつかに到着するかどうかに関係なく、すべての要素のシングルクリックイベントをページにバインドすることができます。

$(document).bind('click', function (e) {
   var target = $(e.target);
   if (target.is('.myclass')) {
      e.preventDefault(); // if you want to cancel the event flow
      // do something
   } else if (target.is('.myotherclass')) {
      e.preventDefault();
      // do something else
   }
});

しばらく使っていました。魅力のように働きます。

JQuery 1.7以降では、bindや他のイベント委譲メソッドの代わりに.on()を使用することをお勧めしますが、.bind()はまだ機能します。

2
i--

あなたのjQuery 1.3以降の場合は. live() を使用してください。

現在および将来に一致するすべての要素のハンドラをイベント(clickなど)にバインドします。カスタムイベントをバインドすることもできます。

1
redsquare

live()関数を使いたいのです。 the docs を参照してください。

例えば:

$("#anchor1").live("click", function() {
    $("#anchor1").append('<a class="myclass" href="#">test4</a>');
});
1
Adam Bellaire