2010-06-27 4 views
5

Könnte mir jemand sagen, warum dieser Code:jQuery, Ereignis klicken, wird zu viel Rekursion

$('#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'); 
     } 
}) 

zu viel Rekursionsfehlers werfen ...

Grüße

Antwort

1

Wenn Sie löst der "Klick" Es ist nicht wirklich eine separate Ereignis Dispatch-Schleife — jQuery wird die Handler genau dort und dann laufen. Da Ihre <input>innerhalb Ihre <td> ist, wird das Ereignis auf die <td> selbst sprudeln, wo es wieder in diesen Handler laufen wird.

Beachten Sie auch, dass diese Zeile hier:

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

ist vielleicht nicht das, was Sie wollen - ich denke, dass immer das Wort log werden „gesperrt“. Vielleicht bedeuten Sie

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

Ich benutze Firebug Konsole, so in meinem Fall funktioniert alles wie erwartet. – Marek

6

Ereignis Blubbern zu verhindern, legt event.stopPropagation() in der Prozedur für Ihr input Click-Ereignis des Elements.

$('#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: Als @Pointy erwähnt, kann es Ihre Absicht, die gleiche sein Handler beide Ereignisse behandeln zu haben, oder zumindest die td Handler noch feuern, wenn Sie klicken auf die input.

Wenn das der Fall ist, müssen Sie nur überprüfen müssen, um zu sehen, ob die td Handler durch einen Klick auf das input gefeuert wurde, und wenn ja, verhindern, dass die input.trigger("click") ab:

$('#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'); 
      } 
     } 
}); 

Ein anderer Weg, zu tun, würde der Test sein: Beide Ansätze

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

davon ausgehen, dass es nur eine input. Wenn dies nicht der Fall ist, müssen Sie der Eingabe eine Kennung geben, damit der Test spezifischer wird.

+0

Das stimmt, aber ich muss mich fragen, ob das eine gute Idee wäre. Wenn er tatsächlich mit "Klick" auf dem ''-Level umgehen will, kann es schlecht sein, die Blasenbildung bei der' ' zu annullieren, da dies die Klicks auf die '' ableitet. Natürlich kommt es darauf an, was noch in der Tabellenzelle ist. – Pointy

+0

@ Pointy - Du hast Recht. Meine Annahme ist, dass der Klick für das "td" an anderer Stelle im "td" auftritt, und daher wäre der Handler getrennt. Wenn das nicht der Fall ist, wird OP wahrscheinlich das 'evt.target' im' td'-Handler testen müssen, um zu sehen, ob der Klick auf dem 'input' war, und wenn dies der Fall ist, wird das' click() 'nicht aktiviert die "Eingabe". – user113716

+0

Gute Antwort, +1 – Mark