Zdarzenie Click nie działa na dynamicznie generowanych elementach [duplikat]

to pytanie ma już odpowiedzi tutaj : powiązanie zdarzeń z dynamicznie tworzonymi elementami? (23 odpowiedzi) Zamknięty 3 lata temu .
<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>

Próbowałem wygenerować nowy tag z nazwą klasy test w <h2> klikając przycisk. Zdefiniowałem również zdarzenie kliknięcia związane z test. Ale impreza nie działa.

Czy ktoś może pomóc?
 516
Author: Cᴏʀʏ, 2011-07-12

20 answers

Wiązanie click(), którego używasz, nazywa się wiązaniem "bezpośrednim", które dołącza obsługę tylko do elementów, które już istnieją. Nie będzie związany z elementami stworzonymi w przyszłości. Aby to zrobić, musisz utworzyć" delegowane " Wiązanie za pomocą on().

Zdarzenia delegowane mają tę zaletę, że mogą przetwarzać zdarzenia z elementów potomnych, które są dodawane do dokumentu później czas.

źródło

Oto czego szukasz:

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>

Powyższe działa dla osób korzystających z jQuery w wersji 1.7+. Jeśli używasz starszej wersji, zapoznaj się z poprzednią odpowiedzią poniżej.


Poprzednia Odpowiedź :

Spróbuj użyć live():

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


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

Zadziałało dla mnie. próbowałem z jsFiddle.

Albo jest nowy sposób na zrobienie tego z delegate():

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

Zaktualizowany jsFiddle .

 748
Author: Cᴏʀʏ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-09 18:30:53

Użyj .on() Metoda z delegowanymi zdarzeniami

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

The .on() metoda pozwala na delegowanie dowolnej funkcji obsługi zdarzeń do:
bieżące elementy lub przyszłe elementy dodane do DOM w późniejszym czasie.

P. S: nie używaj .live()! Od jQuery 1.7 + Metoda .live() jest przestarzała.

 244
Author: Roko C. Buljan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-24 23:24:14

Powód:

W jQuery Zdarzenie Click() wiąże element tylko wtedy, gdy dany element istnieje w kodzie Html (po załadowaniu strony).

Nie będzie uwzględniał przyszłych elementów, które są tworzone dynamicznie (element przyszłości). Elementy dynamiczne są tworzone przy pomocy javascript lub jquery (Nie w Html) .

Więc normalne Zdarzenie kliknięcia nie będzie uruchamiane na elemencie dynamicznym.

Rozwiązanie:

Aby to przezwyciężyć powinniśmy użyć on () funkcja. on () może delegować Zdarzenie zarówno dla obecnych, jak i przyszłych elementów.

Funkcje

Delegate (), live () i on () mają przewagę nad elementami DOM.

Delegate () i live () są przestarzałe(nie używaj ich).

Na {[4] } może wyzwalać tylko istniejące i przyszłe elementy.

Na można rozważyć wszystkie elementy, które są obecne na całej stronie.

Należy użyć w funkcji, Aby wywołać zdarzenie na dynamicznie (przyszłych) tworzonych elementach.

Usuń kod z $(document).gotowe:

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

  alert();

});

Zmień na:

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

  alert('Clicked');

});
 122
Author: Prabhagaran,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-09-21 10:51:41

Dodaj tę funkcję do pliku js. będzie działać na każdej przeglądarce

$(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>
 27
Author: Abhishek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-28 17:29:37

Zmień

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

Do

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

LIVE DEMO

JQuery .live()

 13
Author: qwertymk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-07-12 02:07:06

Musisz użyć .live to działa:

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

Lub jeśli używasz jquery 1.7 + użyj .na :

$(".test").on("click", "p", function(){
   alert();
});
 13
Author: amurra,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-09 16:54:27

Try .live() or .delegate()

Http://api.jquery.com/live/

Http://api.jquery.com/delegate/

Twój element .test został dodany po metodzie .click(), więc nie miał do niego dołączonego zdarzenia. Live i Delegate dają WYZWALACZ tego zdarzenia elementom nadrzędnym, które sprawdzają ich dzieci, więc wszystko dodane później nadal działa. Myślę, że Live sprawdzi całą treść dokumentu, podczas gdy Delegat może być nadany elementowi, więc Delegat jest bardziej wydajny.

Więcej informacji:

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

 8
Author: DSKrepps,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-07-12 02:27:24

Najlepszy sposób zastosowania zdarzenia na dynamicznie generowanej zawartości za pomocą delegowania.

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

Więc Twój kod jest teraz taki

$(document).on("click",".test",function(){
    // code goes here
});
 7
Author: Jay Patel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-12 13:05:42

Znalazłem dwa rozwiązania w dokumentacji jQuery:

Po pierwsze: użyj delegata na ciele lub dokumencie

Np:

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

Odpowiedź: Dołącz obsługę do jednego lub więcej zdarzeń dla wszystkich elementów pasujących do selektora, teraz lub w przyszłości, w oparciu o określony zestaw elementów głównych. link: http://api.jquery.com/delegate/

Po Drugie: Umieść swoją funkcję w "$ (document) ", używając " on " i dołącz ją do element, który chcesz wywołać. Pierwszy parametr to "obsługa zdarzeń", drugi: element, a trzeci: funkcja. Np.:

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

Odpowiedź: procedury obsługi zdarzeń są powiązane tylko z aktualnie wybranymi elementami; muszą istnieć na stronie w momencie, gdy twój kod wywoła .on () . Aby upewnić się, że elementy są obecne i mogą być zaznaczone, wykonaj powiązanie zdarzeń wewnątrz modułu obsługi gotowego dokumentu dla elementów, które są w znaczniki HTML na stronie. Jeśli nowy HTML jest wprowadzany do strony, Zaznacz elementy i dołącz procedury obsługi zdarzeń po umieszczeniu nowego HTML na stronie. Możesz też użyć zdarzeń delegowanych, aby dołączyć obsługę zdarzenia, zgodnie z poniższym opisem ... link: https://api.jquery.com/on/

 6
Author: user3425150,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-17 00:11:47
$(.surrounding_div_class).on( 'click', '.test', function () {
alert( 'WORKS!' );
});

Będzie działać tylko wtedy, gdy DIV z klasą .surrounding_div_class jest bezpośrednim rodzicem obiektu .test

Jeśli w div znajduje się inny obiekt, który będzie wypełniony, to nie zadziała.

 4
Author: Nikolaus Pluta,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-25 14:42:53

Problem polega na tym, że próbujesz powiązać klasę "test" ze zdarzeniem, zanim pojawi się coś z klasą "test" w DOM. Chociaż może się wydawać, że to wszystko jest dynamiczne, to tak naprawdę dzieje się to, że JQuery przechodzi przez DOM i łączy Zdarzenie kliknij, gdy uruchomiona jest funkcja ready(), co dzieje się przed utworzeniem "Kliknij mnie" w zdarzeniu przycisku.

Dodając Zdarzenie" test "Click do przycisku" button " click handler, spowoduje on podłączenie go po poprawny element istnieje w DOM.

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

Użycie live() (jak zauważyli inni) jest innym sposobem, aby to zrobić, ale uznałem, że dobrym pomysłem było również zwrócenie uwagi na drobny błąd w kodzie JS. To, co napisałeś, nie było złe, po prostu musiało być poprawnie ustawione. Uchwycenie, jak działa DOM i JS, jest jedną z trudniejszych rzeczy dla wielu tradycyjnych programistów do owinięcia głowy.

live() jest czystszym sposobem radzenia sobie z tym iw większości przypadków jest prawidłowy sposób. Informatyka zasadniczo jest oglądanie DOM i ponowne okablowanie rzeczy za każdym razem, gdy elementy w nim się zmieniają.

 4
Author: Marc LaFleur,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-21 05:18:21

.funkcja live działa świetnie.

Służy do dynamicznego dodawania elementów do sceny.

$('#selectAllAssetTypes').live('click', function(event){
                    alert("BUTTON CLICKED");
                    $('.assetTypeCheckBox').attr('checked', true);
                });
Pozdrawiam, Ankit.
 3
Author: Ankit Tanna,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-08 09:32:02

JQuery .on Działa ok, ale miałem pewne problemy z renderowaniem implementującym niektóre z powyższych rozwiązań. Mój problem z użyciem .on polega na tym, że w jakiś sposób renderował zdarzenia inaczej niż metoda .hover.

Tak dla twojej wiadomości, dla każdego, kto również może mieć problem. Problem rozwiązałem ponownie rejestrując Zdarzenie hover dla dynamicznie dodawanego elementu:

Ponownie zarejestruj Zdarzenie hover, ponieważ hover nie działa dla dynamicznie tworzonych elementów. więc za każdym razem kiedy tworzę nowy / dynamiczny element dodaję kod hover ponownie. działa doskonale

$('#someID div:last').hover(
    function() {
       //...
    },
    function() {
       //...
    }
);
 3
Author: user2257720,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-08 13:27:55

Pracuję z tabelami dodającymi do nich nowe elementy dynamicznie, a gdy używam on (), jedynym sposobem na to, aby to działało, jest użycie nie dynamicznego rodzica jako:

<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>

Jest to bardzo przydatne, ponieważ aby usunąć zdarzenia związane z on () , możesz użyć off () , a aby użyć zdarzeń raz, możesz użyć one () .

 3
Author: Timbergus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-06 06:11:54

Nie mogłem dostać live lub delegat do pracy na div w lightbox (tinybox).

Użyłem setTimeout pomyślnie, w następujący prosty sposób:

$('#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
Author: Sasha Shepherd,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-07 15:04:39

Możesz również użyć onclick="do_something(this)"wewnątrz elementu

 3
Author: Daryn K.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-17 01:04:30

Jeśli masz dinamowo dodany link do jakiegoś pojemnika lub body:

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

Możesz wziąć jego surowy element javascript i dodać do niego detektor zdarzeń, jak click :

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

Bez względu na to, ile razy dodajesz nową instancję linku, możesz jej używać tak, jakbyś używał funkcji jquery click.

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

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

Więc otrzymasz wiadomość mówiącą

Its ok

Ma lepszą wydajność niż inne alternatywy.

Extra: możesz uzyskać lepszą wydajność unikając jquery i używając zwykłego javascript. Jeśli używasz IE do wersji 8 powinieneś użyć tego polyfill, aby użyć metody addEventListener

if (typeof Element.prototype.addEventListener === 'undefined') {
    Element.prototype.addEventListener = function (e, callback) {
      e = 'on' + e;
      return this.attachEvent(e, callback);
    };
  }
 3
Author: EliuX,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-03 14:26:05

Alternatywną i bardziej zwięzłą alternatywą (IMHO) jest użycie surowej funkcji javascript, która reaguje na zdarzenie on click, a następnie przekazanie elementu docelowego z powrotem do jQuery, jeśli chcesz. Zaletą tego podejścia jest to, że możesz dynamicznie dodawać swój element w dowolnym miejscu, a obsługa kliknięć będzie "po prostu działać" i nie musisz się martwić o delegowanie kontroli do elementów nadrzędnych itd.

Krok 1: zaktualizuj dynamiczny html, aby uruchomić Zdarzenie onclick. Upewnij się, że przekazać obiekt "event" jako argument


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

Krok 2: Utwórz funkcję testową, aby odpowiedzieć na zdarzenie kliknięcia


    function test(e){
        alert();
    });

Opcjonalny krok 3: biorąc pod uwagę, że używasz jQuery, zakładam, że przydatne będzie uzyskanie odniesienia do przycisku source


    function test(e){
        alert();

        // Get a reference to the button
        // An explanation of this line is available here
        var target = (e.target)? e.target : e.srcElement;

        // Pass the button reference to jQuery to do jQuery magic
        var $btn = $(target);

    });

 3
Author: Nick Mitchell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-30 06:48:51

Można dodawać po kliknięciu do dynamicznie tworzonych elementów. Przykład poniżej. Używając kiedy, aby upewnić się, że jest zrobione. W moim przykładzie chwytam div z klasą expand, dodając" Kliknij, aby zobaczyć więcej " span, a następnie używając tego zakresu, aby ukryć / pokazać oryginalny div.

$.when($(".expand").before("<span class='clickActivate'>Click to see more</span>")).then(function(){
    $(".clickActivate").click(function(){
        $(this).next().toggle();
    })
});
 2
Author: Daryl H,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-14 19:16:36

Użyj 'on', gdy kliknięcie spowoduje powiązanie z elementami już obecnymi.

Dla NP

$('test').on('click',function(){
    alert('Test');
})
To pomoże.
 0
Author: Abhijit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-01 10:08:35