W jQuery, jak dołączyć zdarzenia do dynamicznych elementów html? [duplikat]

To pytanie ma już odpowiedź tutaj:

Załóżmy, że mam jakiś kod jQuery, który dołącza obsługę zdarzeń do wszystkich elementów z klasą "myclass". Na przykład:

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

A mój html może wyglądać następująco:

<a class="myclass" href="#">test1</a>
<a class="myclass" href="#">test2</a>
<a class="myclass" href="#">test3</a>
To działa bez problemu. Zastanów się jednak, czy elementy "myclass" zostały napisane na stronie w przyszłości.

Na przykład:

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

W tym przypadku link "test4" jest tworzony, gdy użytkownik kliknie na # anchor1.

Link "test4" nie ma powiązanej z nim funkcji obsługi click (), mimo że posiada class="myclass".

Wiesz, jak Mogę to naprawić?

Zasadniczo, chciałbym napisać obsługę click() raz i mieć zastosowanie zarówno do treści obecnych przy ładowaniu strony, jak i treści wniesionych później przez Ajax/DHTML.

Author: frankadelic, 2009-08-31

8 answers

Dodaję nową odpowiedź, aby odzwierciedlić zmiany w późniejszych wydaniach jQuery. The .metoda live() jest przestarzała od wersji jQuery 1.7.

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

Od jQuery 1.7,metoda live() jest przestarzała. Użyj .włączone (), aby dołączyć procedury obsługi zdarzeń. Użytkownicy starszych wersji jQuery powinni korzystać .delegate() w preferencjach do .live ().

Dla jQuery 1.7 + można dołączyć obsługę zdarzenia do elementu nadrzędnego za pomocą .on () i podaj selektor a w połączeniu z "myclass" jako argumentem.

Zobacz http://api.jquery.com/on/

Więc zamiast...
$(".myclass").click( function() {
    // do something
});
Możesz pisać...
$('body').on('click', 'a.myclass', function() {
    // do something
});

Będzie to działać dla wszystkich znaczników z 'myclass' w ciele, niezależnie od tego, czy są już obecne, czy dynamicznie dodane później.

Znacznik body jest tutaj używany, ponieważ przykład nie miał bliżej statycznego znacznika otaczającego, ale każdy znacznik nadrzędny, który istnieje, gdy .na wywołanie metody będzie działać. Na przykład znacznik ul dla listy, która będzie miała dodawane elementy dynamiczne wyglądałyby tak:

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

Tak długo, jak istnieje znacznik ul, to będzie działać(elementy li nie muszą jeszcze istnieć).

 782
Author: Sean,
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-07-08 12:36:10

Czasami robienie tego (najczęściej głosowana ODPOWIEDŹ) nie zawsze wystarczy:

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

Może to być problem z powodu wywoływania procedur obsługi zdarzeń. Jeśli to zrobisz, ale powoduje to problemy ze względu na kolejność, w jakiej jest obsługiwane.. Zawsze można to zawinąć w funkcję, która po wywołaniu "odświeża" słuchacza.

Na przykład:

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

Ponieważ jest to funkcja, ilekroć ustawiam mój słuchacz w ten sposób, zwykle wywołuję ją w dokumencie gotowe:

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

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

Następnie, za każdym razem, gdy dodasz jakiś dynamicznie dodany element, wywołaj tę metodę ponownie:

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

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

Miejmy nadzieję, że to pomoże!

Pozdrawiam,

 65
Author: Chandler Zwolle,
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-05-18 13:29:33

Po jQuery 1.7 preferowanymi metodami są .on () i .off()

Odpowiedź Seana pokazuje przykład.

Now Deprecated:

Użyj funkcji jQuery.live() oraz .die(). Dostępny w jQuery 1.3x

From the docs:

Aby wyświetlić tekst każdego akapitu w pole alarmowe po kliknięciu:

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

Również wtyczka livequery robi to i ma wsparcie dla kolejnych wydarzeń.

 36
Author: Matt Brunell,
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-05-23 12:34:51

Jeśli dodajesz stos anchorów do DOM, spójrz na delegację zdarzeń.

Oto prosty przykład:

$('#somecontainer').click(function(e) {   
  var $target = $(e.target);   
  if ($target.hasClass("myclass")) {
    // do something
  }
});
 5
Author: ScottE,
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-19 18:05:12

Wiąże funkcję obsługi zdarzenia (np. click) dla wszystkich dopasowanych elementów. Może również wiązać niestandardowe zdarzenia.

Link text

$(function(){
    $(".myclass").live("click", function() {
        // do something
    });
});
 3
Author: andres descalzo,
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
2009-08-31 19:32:46

Możesz powiązać Zdarzenie pojedynczego kliknięcia ze stroną dla wszystkich elementów, bez względu na to, czy są już na tej stronie, czy też pojawią się w przyszłości, w ten sposób:

$(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
   }
});
Używam go od jakiegoś czasu. Działa jak urok.

W jQuery 1.7 i późniejszych zaleca się użycie .on() zamiast bind lub innej metody delegowania zdarzeń, ale .bind() nadal działa.

 2
Author: i--,
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-29 15:15:42

If your on jQuery 1.3 + then use .live()

Wiąże handler ze zdarzeniem (jak kliknij) dla wszystkich obecnych - i przyszłych - dopasowany element. Może również wiązać niestandardowe wydarzenia.

 1
Author: redsquare,
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
2009-08-31 19:31:26

Chcesz użyć funkcji live(). Zobacz dokumenty .

Na przykład:

$("#anchor1").live("click", function() {
    $("#anchor1").append('<a class="myclass" href="#">test4</a>');
});
 1
Author: Adam Bellaire,
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
2009-08-31 19:31:52