Począwszy od jQuery 1.7 powinieneś używać jQuery.fn.on
:
$(staticAncestors).on(eventName, dynamicChild, function() {});
Wcześniej zalecanym podejściem było użycie live()
:
$(selector).live( eventName, function(){} );
Jednak live()
było przestarzałe w 1,7 za on()
i całkowicie usuwa 1,9. live()
Podpis:
$(selector).live( eventName, function(){} );
... można zastąpić następującym on()
podpisem:
$(document).on( eventName, selector, function(){} );
Na przykład, jeśli twoja strona dynamicznie tworzy elementy z nazwą klasy dosomething
, powiążesz zdarzenie z rodzicem, który już istnieje (jest to sedno problemu tutaj, potrzebujesz czegoś, co istnieje, aby się z nim połączyć, nie łącz z zawartość dynamiczna), może to być (i najłatwiejsza opcja) document
. Pamiętaj document
jednak, że może nie być najbardziej wydajną opcją .
$(document).on('mouseover mouseout', '.dosomething', function(){
// what you want to happen when mouseover and mouseout
// occurs on elements that match '.dosomething'
});
Każdy rodzic, który istnieje w momencie powiązania zdarzenia, jest w porządku. Na przykład
$('.buttons').on('click', 'button', function(){
// do something here
});
dotyczyłby
<div class="buttons">
<!-- <button>s that are generated dynamically and added here -->
</div>
Istnieje dobre wytłumaczenie w dokumentacji
jQuery.fn.on
.W skrócie:
Dlatego w poniższym przykładzie
#dataTable tbody tr
musi istnieć przed wygenerowaniem kodu.Jeśli do strony wstrzykuje się nowy kod HTML, lepiej jest użyć zdarzeń delegowanych w celu dołączenia procedury obsługi zdarzeń, jak opisano poniżej.
Zdarzenia delegowane mają tę zaletę, że mogą przetwarzać zdarzenia z elementów potomnych, które są dodawane do dokumentu w późniejszym czasie. Na przykład, jeśli tabela istnieje, ale wiersze są dodawane dynamicznie za pomocą kodu, następujące elementy ją obsłużą:
Oprócz zdolności do obsługi zdarzeń na elementach potomnych, które nie zostały jeszcze utworzone, kolejną zaletą zdarzeń delegowanych jest ich potencjał znacznie niższego obciążenia, gdy wiele elementów musi być monitorowanych. W tabeli danych zawierającej 1000 wierszy
tbody
pierwszy przykład kodu dołącza moduł obsługi do 1000 elementów.Podejście z delegowanymi zdarzeniami (drugi przykład kodu) dołącza moduł obsługi zdarzenia do tylko jednego elementu
tbody
, a zdarzenie musi tylko przejść w górę o jeden poziom (od kliknięciatr
dotbody
).Uwaga: Zdarzenia delegowane nie działają w przypadku SVG .
źródło
tr
na odpowiedni selektor, na przykład'input[type=checkbox]'
, i byłoby to automatycznie obsługiwane dla nowo wstawianych wierszy?To jest czyste rozwiązanie JavaScript bez bibliotek lub wtyczek:
gdzie
hasClass
jestLive demo
Podziękowania należą się Dave'owi i Sime'owi Vidasowi
Za pomocą bardziej nowoczesnego JS
hasClass
można zaimplementować jako:źródło
Element.classList
nie jest obsługiwany w starszych przeglądarkach. Na przykład IE <9.Możesz dodawać zdarzenia do obiektów podczas ich tworzenia. Jeśli dodajesz te same zdarzenia do wielu obiektów w różnych momentach, dobrym rozwiązaniem może być utworzenie nazwanej funkcji.
źródło
Możesz po prostu zawinąć wywołanie powiązania zdarzenia w funkcję, a następnie wywołać go dwukrotnie: raz w dokumencie gotowy i raz po zdarzeniu, które dodaje nowe elementy DOM. Jeśli to zrobisz, będziesz chciał uniknąć podwójnego wiązania tego samego zdarzenia z istniejącymi elementami, więc musisz usunąć powiązanie istniejących zdarzeń lub (lepiej) powiązać tylko z nowo utworzonymi elementami DOM. Kod wyglądałby mniej więcej tak:
źródło
Spróbuj użyć
.live()
zamiast.bind()
;.live()
zwiąże.hover
do wyboru po zgłoszeniu wniosku sporządzi Ajax.źródło
live()
została wycofana w wersji 1.7 na korzyśćon
i usunięta w wersji 1.9.Wiązanie zdarzeń na dynamicznie tworzonych elementach
Pojedynczy element:
Element podrzędny:
Zwróć uwagę na dodane
*
. Wydarzenie zostanie uruchomione dla wszystkich dzieci tego elementu.Zauważyłem to:
To już nie działa, ale działało wcześniej. Korzystam z jQuery z Google CDN , ale nie wiem, czy to zmienili.
źródło
Możesz użyć metody live (), aby powiązać elementy (nawet te nowo utworzone) ze zdarzeniami i modułami obsługi, takimi jak zdarzenie onclick.
Oto przykładowy kod, który napisałem, gdzie możesz zobaczyć, w jaki sposób metoda live () wiąże wybrane elementy, nawet te nowo utworzone, ze zdarzeniami:
źródło
Wolę używać selektora i stosuję go na dokumencie.
To wiąże się z dokumentem i będzie miało zastosowanie do elementów, które będą renderowane po załadowaniu strony.
Na przykład:
źródło
selector
zmiennej, gdy musi ona zawierać ciąg lub obiekt Element, który można po prostu przekazać bezpośrednio do argumentuon()
Innym rozwiązaniem jest dodanie detektora podczas tworzenia elementu. Zamiast wstawiać detektor do ciała, wstawiasz detektor do elementu w momencie jego tworzenia:
źródło
myElement.append('body');
musi byćmyElement.appendTo('body');
. Z drugiej strony, jeśli nie ma potrzeby dalszego stosowania zmiennejmyElement
jest to łatwiejsze i krótsze w ten sposób:$('body').append($('<button/>', { text: 'Go to Google!' }).bind( 'click', goToGoogle));
Spróbuj w ten sposób -
źródło
Zwróć uwagę na klasę „MAIN”, w której element jest umieszczony, na przykład
W powyższym scenariuszu GŁÓWNY obiekt, który będzie oglądać jQuery, to „kontener”.
Wtedy w zasadzie mają elementy nazwy pod pojemnikiem, takich jak
ul
,li
orazselect
:źródło
możesz użyć
lub
te dwie metody są równoważne, ale mają inną kolejność parametrów.
patrz: jQuery Delegate Event
źródło
delegate()
jest teraz przestarzałe Nie używaj tego.Możesz dołączyć zdarzenie do elementu, gdy jest tworzone dynamicznie za pomocą
jQuery(html, attributes)
.źródło
Odbywa się to poprzez delegowanie wydarzeń . Zdarzenie zostanie powiązane z elementem klasy opakowania, ale zostanie delegowane do elementu klasy selektora. Tak to działa.
Uwaga:
elementem klasy otoki może być cokolwiek np. dokument, treść lub opakowanie. Opakowanie powinno już istnieć . Jednak
selector
niekoniecznie musi być prezentowane podczas ładowania strony. Może przyjść później, a wydarzenie będzie się wiązałoselector
bezbłędnie .źródło
Oto dlaczego dynamicznie tworzone elementy nie reagują na kliknięcia:
Aby obejść ten problem, należy odsłuchać wszystkie kliknięcia i sprawdzić element źródłowy:
Nazywa się to „delegowaniem zdarzeń”. Dobra wiadomość, jest to wbudowana funkcja w jQuery :-)
źródło
Wszelkie strony, które istnieją w momencie powiązania zdarzenia, a jeśli twoja strona dynamicznie tworzy elementy za pomocą przycisku nazwy klasy , powiążesz zdarzenie z rodzicem, który już istnieje
źródło
Powiąż zdarzenie z rodzicem, który już istnieje:
źródło
Skorzystaj z
.on()
metody jQuery http://api.jquery.com/on/ aby dołączyć procedury obsługi zdarzeń do elementu live.Również od wersji 1.9
.live()
metoda jest usuwana.źródło
Wolę mieć detektory zdarzeń wdrożone w sposób modułowy niż skrypty
document
detektora zdarzeń poziomu. Lubię to poniżej. Uwaga: nie można nadpisać elementu z tym samym detektorem zdarzeń, więc nie martw się o dołączenie detektora więcej niż jeden raz - tylko jeden drążek.źródło
Kolejne elastyczne rozwiązanie do tworzenia elementów i łączenia zdarzeń ( źródło )
Uwaga: Spowoduje to utworzenie instancji procedury obsługi zdarzeń dla każdego elementu (może mieć wpływ na wydajność, gdy jest używany w pętlach)
źródło
źródło
Szukałem rozwiązania, aby uzyskać
$.bind
i$.unbind
pracować bez problemów w dynamicznie dodawanych elementach.Jak na () robi sztuczkę, aby dołączyć zdarzenia, aby stworzyć fałszywe unbind na tych, do których przyszedłem:
źródło