2010-06-27 10 views
5

Czy ktoś mógłby mi powiedzieć, dlaczego ten kod:jQuery, kliknij zdarzenie, zbyt dużo rekursji

$('#places-view > tbody').find('td').click(function(evt) { 
    var td = $(this), 
     input = td.find('input'); 
     console.log('click'); 
     console.log(input.attr('disabled'), 'disabled'); 
     if (! input.attr('disabled')) { 
      input.trigger('click'); 
      console.log('inner click'); 
     } 
}) 

rzuca zbyt dużo błędów rekurencji ...

Pozdrowienia

Odpowiedz

1

Kiedy wywołać „kliknięcie” , to naprawdę nie jest osobna pętla ekspedycji zdarzeń — jQuery będzie uruchamiać programy obsługi tam i teraz. Ponieważ twój <input> jest wewnątrz twój <td>, wydarzenie będzie bańka się do samego siebie, <td>, gdzie będzie ponownie trafić w ten uchwyt ponownie.

Należy również pamiętać, że ta linia tutaj:

console.log(input.attr('disabled'), 'disabled'); 

nie jest być może to, co chcesz - Myślę, że będziemy zawsze zalogować słowo „wyłączone”. Może chodziło

console.log(input.attr('disabled') + ' disabled'); 
+0

Używam konsoli firebug, więc w moim przypadku wszystko działa zgodnie z oczekiwaniami. – Marek

6

Aby uniknąć pęcherzyków zdarzeń, umieść event.stopPropagation() w module obsługi zdarzenia Click Twojego input elementu.

$('#places-view input').click(function(event) { 

     // This will prevent the click event from bubbling up and firing 
     // the click event on your <td> 
    event.stopPropagation(); 

     // run the rest of your click code 
}); 

http://api.jquery.com/event.stopPropagation/


EDIT: W @Pointy zauważyć, może być twój zamiar mieć takie same obsługi obsługiwać zarówno wydarzenia, albo przynajmniej mają obsługi td nadal ognia, gdy klikniesz na input.

Jeśli o to chodzi, to po prostu trzeba sprawdzić, czy funkcja obsługi td został zwolniony przez kliknięcie na input, a jeśli tak, to zapobiec input.trigger("click") z systemem:

$('#places-view > tbody').find('td').click(function(evt) { 
    var td = $(this), 
     input = td.find('input'); 
     console.log('click'); 
     console.log(input.attr('disabled'), 'disabled'); 
     if (! input.attr('disabled')) { 
       // If the target of the click was not the input, 
       // then trigger the click on the input 
      if(input.not(evt.target).length) { 
       input.trigger('click'); 
       console.log('inner click'); 
      } 
     } 
}); 

Innym sposobem zrobić test będzie:

if(input[0] != evt.target) {... 

Oba te podejścia zakładają, że istnieje tylko jeden input. Jeśli tak nie jest, musisz podać identyfikator wejściowy, aby umożliwić bardziej szczegółowy test.

+0

To prawda, ale muszę się zastanowić, czy to byłby dobry pomysł. Jeśli rzeczywiście chce obsłużyć "kliknięcie" na poziomie '', może być źle anulować bulgotanie w '', ponieważ spowoduje to odstąpienie od kliknięć do ''. Oczywiście zależy to od tego, co jeszcze jest w komórce tabeli. – Pointy

+0

@Pointy - Masz rację. Zakładam, że kliknięcie dla 'td' występuje w innym miejscu' td', i jako takie, program obsługi byłby oddzielny. Jeśli tak nie jest, to OP będzie prawdopodobnie musiał przetestować 'evt.target' w' td' handler, aby zobaczyć, czy kliknięcie było na 'wejściu', a jeśli tak, obejść wyzwalanie' click() 'na "wejście". – user113716

+0

Dobra odpowiedź, +1 – Mark

Powiązane problemy