web-dev-qa-db-ja.com

Clickイベントは動的に生成された要素には機能しません

<html>
<head>
    <script type="text/javascript" src="jquery.js"></script>
    <script type="text/javascript">

        $(document).ready(function() {

            $("button").click(function() {
                $("h2").html("<p class='test'>click me</p>")
            });   

            $(".test").click(function(){
                alert();
            });
        });

    </script>
</head>
<body>
    <h2></h2>
    <button>generate new element</button>
</body>
</html>

ボタンをクリックして<h2>にクラス名testを持つ新しいタグを生成しようとしていました。 testに関連するクリックイベントも定義しました。しかし、イベントは機能しません。

誰も手伝ってくれる?

442
cheng

あなたが使っているclick()バインディングは "直接"バインディングと呼ばれ、既に存在する要素にハンドラを結び付けるだけです。将来作成される要素に縛られることはありません。それには、 on() を使用して "委任"バインディングを作成する必要があります。

デリゲートイベントには、後でドキュメントに追加された子孫要素からのイベントを処理できるという利点があります。

出典

これがあなたが探しているものです:

var counter = 0;

$("button").click(function() {
    $("h2").append("<p class='test'>click me " + (++counter) + "</p>")
});

// With on():

$("h2").on("click", "p.test", function(){
    alert($(this).text());
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<h2></h2>
<button>generate new element</button>

上記はjQueryバージョン1.7以降を使っている人のために働きます。古いバージョンを使用している場合は、以下の以前の回答を参照してください。


前回の回答

live() :を使ってみてください。

$("button").click(function(){
    $("h2").html("<p class='test'>click me</p>")
});   


$(".test").live('click', function(){
    alert('you clicked me!');
});

私のために働きました。 試してみた jsFiddle付き。

あるいは、 delegate() でそれをするための新たな方法があります。

$("h2").delegate("p", "click", function(){
    alert('you clicked me again!');
});

更新されたjsFiddle

639
Cᴏʀʏ

デリゲートイベントで .on()メソッドを使用する

$('#staticParent').on('click', '.dynamicElement', function() {
    // Do something on an existent or future .dynamicElement
});

.on()メソッドを使用すると、目的のイベントハンドラを次のように委任できます。
current elementsまたは future elementsが後でDOMに追加されました。

P.S:.live()を使用しないでください! jQuery 1.7以降から、.live()メソッドは非推奨になりました。

204
Roko C. Buljan

理由:

JQueryでは、Click() - 要素がHTMLコード内にすでに存在する場合にのみイベントハンドラを添付します。

ページが読み込まれた後に動的に作成される新しい要素(Future要素)は考慮されません。

動的要素は javascriptまたはjquery(HTMLにはありません) の助けを借りて作成されます。

クリックイベントは発生しません。

解決策:

これを克服するには、 on() functionを使用する必要があります。

delegate()、live() 、および on() 関数には、DOM要素を超える利点があります。

on は、既存の要素と将来の要素の両方をトリガーできます。

on は、ページ全体に存在するすべての要素を考慮できます。

delegate()、live()関数は非推奨です(これらを使用しないでください)。

動的に作成された(将来の)要素でイベントを起動するには、 on functionを使用する必要があります。

$(document).readyからコードを削除します。

$(".test").click(function(){

  alert();

});

着替える:

$(document).on('click','.test',function(){

  alert('Clicked');

});
87
Prabhagaran

jsファイルにこの関数を追加してください。 すべてのブラウザで動作します

$(function() {
    $(document).on("click", '#mydiv', function() {
        alert("You have just clicked on ");
    });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id='mydiv'>Div</div>
18
Abhishek

変化する

 $(".test").click(function(){

 $(".test").live('click', function(){

ライブデモ

jQuery .live()

12
qwertymk

これを機能させるには .live を使用する必要があります。

$(".test").live("click", function(){
   alert();
});

または、jquery 1.7以降を使用している場合は .on :を使用してください。

$(".test").on("click", "p", function(){
   alert();
});
11
amurra

.live()または.delegate()を試してください

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

http://api.jquery.com/delegate/

あなたの.test要素は.click()メソッドの後に追加されたので、それにはイベントが付加されていません。 LiveとDelegateは、それらの子をチェックする親要素にそのイベントトリガーを与えるので、後で追加されたものはまだうまくいきます。私は、Liveがドキュメント本体全体をチェックすると考えていますが、デリゲートは要素に与えることができるので、デリゲートはより効率的です。

より詳しい情報:

http://www.alfajango.com/blog/the-difference-between-jquerys-bind-live-and-delegate/ /

7
DSKrepps

私はjQueryのドキュメントで2つの解決策を見つけました:

最初:BodyまたはDocumentにデリゲートを使う

例えば:

 $("body").delegate('.test', 'click', function(){
 ...
  alert('test');
 });

どうして?

答え: 特定のルート要素のセットに基づいて、現在または将来セレクタに一致するすべての要素の1つ以上のイベントにハンドラをアタッチします。リンク: http://api.jquery.com/delegate/

2番目に、あなたの関数を"$(document)"に置き、"on"を使い、これをトリガーしたい要素に付けます。最初のパラメータは "イベントハンドラ"、2番目の要素は要素、3番目のパラメータは関数です。例えば:

 $( document ).on( 'click', '.test', function () {
 ...
  alert('test');
 });

どうして?

答え: イベントハンドラは現在選択されている要素にのみバインドされます。コードが.on()を呼び出した時点でそれらがページに存在している必要があります。要素が存在し、選択できるようにするには、ページ上のHTMLマークアップ内にある要素に対してdocument readyハンドラ内でイベントバインディングを実行します。新しいHTMLがページに挿入されている場合は、新しいHTMLがページに配置された後に要素を選択し、イベントハンドラを添付します。または、次に説明するように、デリゲートイベントを使用してイベントハンドラを添付します。link: https://api.jquery.com/on/

6
user3425150

委任を使用して動的に生成されたコンテンツにイベントを適用するための最良の方法。

$(document).on("eventname","selector",function(){
    // code goes here
});

だからあなたのコードは今このようなものです

$(document).on("click",".test",function(){
    // code goes here
});
5
Jay Patel

あなたが持っている問題は、あなたがDOMで「テスト」クラスを使って何がある前に、イベントに「テスト」クラスをバインドしようとしているということです。これはすべて動的であるようにそれが見えるかもしれませんが、実際に何が起こっているかJQueryDOMワイヤアップあなたのボタンイベントに「私をクリックして」作成の前に起こるready()関数は解雇クリックイベント、オーバーパスになります。

"test" Clickイベントを "button"クリックハンドラに追加することで、正しい要素がDOMに存在した後にそれを配線します。

<script type="text/javascript">
    $(document).ready(function(){                          
        $("button").click(function(){                                  
            $("h2").html("<p class='test'>click me</p>")                          
            $(".test").click(function(){                          
                alert()                          
            });       
        });                                     
    });
</script>

(他の人が指摘したように)live()使用することでこれを実行する別の方法ですが、私はあなたのJSコードにマイナーな誤りを指摘することも良いアイデアだと感じました。あなたが書いたものは間違っていませんでした、それはただ正しいスコープである必要がありました。 DOMとJSがどのように機能するかを把握することは、多くの伝統的な開発者が頭を包み込むのが難しいことの1つです。

live()はこれを処理するためのよりクリーンな方法であり、ほとんどの場合正しい方法です。それは本質的にDOMを監視し、その中の要素が変わるたびに物事を再配線します。

4
Marc LaFleur
$(.surrounding_div_class).on( 'click', '.test', function () {
alert( 'WORKS!' );
});

クラス.surrounding_div_classのDIVがオブジェクト.testの直接の親である場合にのみ機能します

Divに入力される別のオブジェクトがある場合、機能しません。

4
Nikolaus Pluta

生きている機能はすばらしい働きます。

これは、ステージに動的に追加された要素用です。

$('#selectAllAssetTypes').live('click', function(event){
                    alert("BUTTON CLICKED");
                    $('.assetTypeCheckBox').attr('checked', true);
                });

乾杯、Ankit。

3
Ankit Tanna

あなたが何らかのコンテナまたは本体への動的に追加されたリンクを持っているならば:

var newLink= $("<a></a>", {
        "id": "approve-ctrl",
        "href": "#approve",
        "class": "status-ctrl",
        "data-attributes": "DATA"
    }).html("Its ok").appendTo(document.body);

click のように、生のjavascript要素を使ってイベントリスナーを追加できます。

newLink.get(0).addEventListener("click", doActionFunction);

この新しいリンクインスタンスを何回追加しても、jqueryのclick関数を使用しているかのように使用できます。

function doActionFunction(e) {
    e.preventDefault();
    e.stopPropagation();

    alert($(this).html());
}

だからあなたはというメッセージを受け取るでしょう

大丈夫です

他の方法よりもパフォーマンスが優れています。

Extra :あなたはjqueryを避けて普通のjavascriptを使うことでより良いパフォーマンスを得ることができます。バージョン8までIEを使用している場合は、このpolyfillを使用してメソッドaddEventListenerを使用する必要があります。

if (typeof Element.prototype.addEventListener === 'undefined') {
    Element.prototype.addEventListener = function (e, callback) {
      e = 'on' + e;
      return this.attachEvent(e, callback);
    };
  }
3
EliuX

もう1つのもっと簡潔な代替手段(IMHO)は、on clickイベントに応答する生のjavascript関数を使用し、必要に応じてターゲット要素をjQueryに渡すことです。この方法の利点は、要素を動的にどこにでも追加できることです。クリックハンドラは「動作する」だけで、親要素に制御を委任することなどを気にする必要はありません。

ステップ1: onclickイベントを発生させるために動的HTMLを更新する。引数として 'event'オブジェクトを渡すようにしてください

 
 $( "ボタン")。クリック(function(){
 $( "h2")。html( "<p class = 'test'  onclick = 'test(event)'  >クリックしてください</p> ")
}); 
 

ステップ2: クリックイベントに応答するテスト関数を作成する

 
機能テスト(e){
 alert(); 
}); 
 

オプションのステップ3: あなたがjQueryを使用していると仮定すると、ソースボタンへの参照を取得することは有用であろうと思います

 
機能テスト(e){
] alert(); 
 
 //ボタンへの参照を取得
 //この行の説明があります ここ 
 var target =(e.target)? e.target:e.srcElement; 
 
 // jQueryを実行するためにjQueryにボタン参照を渡す
 var $ btn = $(target); 
 
}); 
 
3
Nick Mitchell

ライトボックス(tinybox)でdivを動作させることができませんでした。

次の簡単な方法で、setTimeoutをうまく使いました。

$('#displayContact').click(function() {
    TINY.box.show({html:'<form><textarea id="contactText"></textarea><div id="contactSubmit">Submit</div></form>', close:true});
    setTimeout(setContactClick, 1000);
})

function setContactClick() {
    $('#contactSubmit').click(function() {
        alert($('#contactText').val());
    })
}
3
Sasha Shepherd

要素の中にonclick="do_something(this)"を使うこともできます

3
Daryn K.

Jqueryの.onは問題なく動作しますが、上記の解決策のいくつかを実装したレンダリングで問題が発生しました。私が.onを使用する際の問題は、どういうわけかそれがイベントを.hoverメソッドと異なってレンダリングしていたということです。

また問題を抱えているかもしれない他の誰かのためのただのファイ。動的に追加されたアイテムのホバーイベントを再登録することで問題を解決しました。

ホバーは動的に作成されたアイテムには機能しないため、ホバーイベントを再登録します。だから私は新しい/動的なアイテムを作成するたびに私は再びホバーコードを追加します。完璧に動作します

$('#someID div:last').hover(
    function() {
       //...
    },
    function() {
       //...
    }
);
3
user2257720

動的に作成された要素にクリックを追加することができます。以下の例それを確実にするためにWhenを使用する。私の例では、クラスを展開してdivをつかみ、 "click to more"スパンを追加してから、そのスパンを使用して元のdivを非表示/表示しています。

$.when($(".expand").before("<span class='clickActivate'>Click to see more</span>")).then(function(){
    $(".clickActivate").click(function(){
        $(this).next().toggle();
    })
});
2
Daryl H

私はテーブルに新しい要素を動的に追加して作業しています、そしてon()を使うときそれが私のために働くようにする唯一の方法は非動的親を使うことです:

<table id="myTable">
    <tr>
        <td></td> // Dynamically created
        <td></td> // Dynamically created
        <td></td> // Dynamically created
    </tr>
</table>

<input id="myButton" type="button" value="Push me!">

<script>
    $('#myButton').click(function() {
        $('#myTable tr').append('<td></td>');
    });

    $('#myTable').on('click', 'td', function() {
        // Your amazing code here!
    });
</script>

on() でバインドされたイベントを削除するには off() を使用でき、イベントを1回使用するには one() を使用できるため、これは非常に便利です。

2
Timbergus

Clickが既に存在する要素にバインドされるように 'on'を使用してください。

例えば

$('test').on('click',function(){
    alert('Test');
})

これは助けになるでしょう。

0
Abhijit