$ (dokument) .on („klik”… nie działa?


83

Czy jest jakiś dobrze znany błąd, który mógłbym tutaj popełnić?

Mam skrypt, który używa .on (), ponieważ element jest generowany dynamicznie i nie działa. Aby to przetestować, zastąpiłem selektor zawijaniem elementu dynamicznego, który jest statyczny i nadal nie działa! Kiedy jednak przełączyłem się na zwykły stary plik .click, aby zawinąć, zadziałało.
(To oczywiście nie zadziała w przypadku elementu dynamicznego, tego, który ma znaczenie).

To działa:

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

To nie:

$(document).on("click","#test-element",function() {
    alert("click");
});

AKTUALIZACJA:

Kliknąłem prawym przyciskiem myszy i wykonałem „Sprawdź element” w przeglądarce Chrome, aby coś dokładnie sprawdzić, a potem zdarzenie kliknięcia zadziałało. Odświeżyłem się i nie działało, sprawdziłem element, a potem zadziałało. Co to znaczy?


1
Czy tworzysz więcej niż jeden element z tym samym identyfikatorem?
adeneo,

Publikowanie samego jQuery bez odpowiedniego kodu HTML utrudnia pomoc.
jmoerdyk

3
Cześć OP, sprawdź wersję Jquery, której używasz, :)lub pstryknij skrzypce, mogę ci pomóc,
Tats_innit

Twój kod ma działać. onFunkcja została dodana w jQuery 1.7, upewnij się, że masz najnowszą wersję. Edycja: dowód dla ciebie, że działa na skrzypcach
Phil-R

Twój drugi przykład działa z najnowszą wersją jQuery 1.x: jsfiddle.net/AJPdS
Wookai.

Odpowiedzi:


153

Używasz poprawnej składni do tworzenia powiązania z dokumentem w celu nasłuchiwania zdarzenia kliknięcia elementu o identyfikatorze = "test-element".

Prawdopodobnie nie działa z jednego z następujących powodów:

  • Nie używasz najnowszej wersji jQuery
  • Brak pakowania kodu w DOM gotowy
  • lub robisz coś, co powoduje, że zdarzenie nie jest widoczne dla słuchacza w dokumencie.

Aby przechwytywać zdarzenia w elementach, które są tworzone PO zadeklarowaniu detektorów zdarzeń - należy powiązać się z elementem nadrzędnym lub elementem znajdującym się wyżej w hierarchii.

Na przykład:

$(document).ready(function() {
    // This WILL work because we are listening on the 'document', 
    // for a click on an element with an ID of #test-element
    $(document).on("click","#test-element",function() {
        alert("click bound to document listening for #test-element");
    });

    // This will NOT work because there is no '#test-element' ... yet
    $("#test-element").on("click",function() {
        alert("click bound directly to #test-element");
    });

    // Create the dynamic element '#test-element'
    $('body').append('<div id="test-element">Click mee</div>');
});

W tym przykładzie zostanie uruchomiony tylko alert „powiązany z dokumentem”.

JSFiddle z jQuery 1.9.1


Niestety korzystam z najnowszej wersji Jquery, mój kod jest odpowiednio opakowany, znajduje się w $ (document) .ready, a klikane zdarzenie jest elementem najniższego poziomu w dokumencie. To jest zaskakujące.
Pan Lavalamp,

Powiedziałbym, że „potrzeba umieszczenia słuchacza na elemencie nadrzędnym” nie jest konieczne, chociaż ja też to polecam. To właśnie bulgotanie umożliwia działanie .on (). Gdybyśmy nie mogli polegać na tym, że bulgotanie minie bezpośredniego rodzica, nie byłoby to świetne rozwiązanie.
iGanja,

@iGanja - słuszna uwaga i jak sugerujesz, „potrzeba” nie jest właściwym słowem, ponieważ istnieją inne, mniej idealne sposoby, aby to osiągnąć. Poprawiłem swoją odpowiedź.
itsmejodie

jeśli używam „this” do odniesienia się do obiektu elementu, to w jaki sposób mogę dołączyć to zdarzenie do dokumentu ..
Ashish Joshi

1
@JasonGlisson, przypuszczam, że podczas gdy masz nasłuchiwanie w dokumencie, jest albo problem z brakiem bulgotania zdarzenia (po kliknięciu przycisku), albo różnica między event.targeti event.currentTargetgdzieś w kodzie, ale jest ich wiele rzeczy, które mogą obejmować wyłączanie zdarzeń wskaźnika na przycisku
itsmejodie

12

Twój kod powinien działać, ale wiem, że odpowiedź ci nie pomoże. Możesz zobaczyć działający przykład tutaj (jsfiddle) .

JQuery:

$(document).on('click','#test-element',function(){
    alert("You clicked the element with and ID of 'test-element'");
});

Jak ktoś już zauważył, zamiast klasy używasz identyfikatora. Jeśli masz więcej niż jeden element na stronie o identyfikatorze, jquery zwróci tylko pierwszy element o tym identyfikatorze . Nie będzie żadnych błędów, bo tak to działa. Jeśli na tym polega problem, zauważysz, że zdarzenie kliknięcia działa w przypadku pierwszego, test-elementale nie w przypadku kolejnych.

Jeśli to nie opisuje dokładnie objawów problemu, być może Twój selektor się myli. Twoja aktualizacja prowadzi mnie do wniosku, że dzieje się tak z powodu sprawdzenia elementu, a następnie ponownego kliknięcia strony i uruchomienia kliknięcia. Może to powodować, jeśli umieścisz detektor zdarzeń na rzeczywistym documentzamiast test-element. Jeśli tak, po kliknięciu dokumentu i ponownym włączeniu (jak z okna programisty z powrotem do dokumentu) zdarzenie zostanie wyzwolone. W takim przypadku zauważysz również, że zdarzenie kliknięcia jest wywoływane, gdy klikniesz między dwiema różnymi kartami (ponieważ są to dwie różne karty documenti dlatego klikasz dokument.

Jeśli żadna z tych odpowiedzi nie jest odpowiedzią, publikowanie HTML znacznie ułatwi zrozumienie tego problemu.


4

Stary post, ale uwielbiam się dzielić, bo mam ten sam przypadek, ale w końcu poznałem problem:

Problem polega na tym, że tworzymy funkcję do pracy z określonym elementem HTML, ale element HTML powiązany z tą funkcją nie został jeszcze utworzony (ponieważ element został wygenerowany dynamicznie). Aby to zadziałało, powinniśmy wykonać funkcję w tym samym czasie, gdy tworzymy element. Najpierw element, niż powiązanie z nim funkcji.

Mówiąc najprościej, funkcja będzie działać tylko w elemencie, który ją utworzył (nim). Wszelkie elementy, które tworzyły się dynamicznie, oznaczają po nim.

Ale proszę sprawdzić tę próbkę, która nie uwzględniła powyższego przypadku:

<div class="btn-list" id="selected-country"></div>

Dołączane dynamicznie:

<button class="btn-map" data-country="'+country+'">'+ country+' </button>

Ta funkcja działa dobrze, klikając przycisk:

$(document).ready(function() {    
        $('#selected-country').on('click','.btn-map', function(){ 
        var datacountry = $(this).data('country'); console.log(datacountry);
    });
})

lub możesz użyć body jak:

$('body').on('click','.btn-map', function(){ 
            var datacountry = $(this).data('country'); console.log(datacountry);
        });

porównaj z tym, że nie działa:

$(document).ready(function() {     
$('.btn-map').on("click", function() { 
        var datacountry = $(this).data('country'); alert(datacountry);
    });
});

mam nadzieję, że to pomoże


Możesz uniknąć używania $ (document) .ready do czekania na dodanie elementu do DOM, jeśli zamiast tego zaczniesz od $ (dokument) .on ("kliknij" ... $ (dokument) .on ("kliknij", „# selected-country”, function () {});
Loren

3

To działa:

<div id="start-element">Click Me</div>

$(document).on("click","#test-element",function() {
    alert("click");
});

$(document).on("click","#start-element",function() {
    $(this).attr("id", "test-element");
});

Oto Fiddle


1
Nie jest to element generowany dynamicznie, jak na pytanie.
itsmejodie

@itsmejodie - uzgodniono, ale jest dynamicznie powiązany z programem obsługi zdarzeń. zmiana identyfikatora zasadniczo nie różni się od dołączenia elementu DOM.
iGanja,

1

Spróbuj tego:

$("#test-element").on("click" ,function() {
    alert("click");
});

Dokumentowy sposób robienia tego również jest dziwny. Miałoby to dla mnie sens, gdyby zostało użyte jako selektor klasy, ale w przypadku id prawdopodobnie masz po prostu bezużyteczny przechodzenie tam przez DOM. W przypadku selektora id otrzymujesz ten element natychmiast.


2
Czym się to różni od $("#test-element").click(function() {?
Sushanth -

2
Musisz użyć .on (), aby powiązać zdarzenia z dynamicznie generowanymi DOMami - wszystko, co jest powiązane z .click (), będzie próbowało połączyć się, gdy dokument będzie gotowy, a jeśli dom nie jest obecny, nic się nie stanie.
JTravakh,

2
Ale użycie .onbez użycia a selectorjest tym samym, co bezpośrednie zastosowanie do niego zdarzenia kliknięcia
Sushanth -

1
To nie jest poprawna odpowiedź na pytanie. Spowoduje to bezpośrednie powiązanie z elementem i dlatego nie jest odpowiednie, gdy element został wygenerowany dynamicznie.
itsmejodie

1
Właściwie przeczytałem dokumentację, ale sekcja dotycząca wydajności tak naprawdę nie ma nic wspólnego z delegowanymi programami obsługi zdarzeń, a Twój kod nie jest delegowanym programem obsługi zdarzeń.
adeneo
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.