2010-06-27 32 views
5

Podría alguien decirme por qué este código:jQuery, haga clic en evento, el exceso de recursividad

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

tirar demasiado de error recursividad ...

Saludos

Respuesta

1

Cuando se dispara el "clic" , en realidad no se trata de un ciclo de envío de eventos por separado — jQuery va a ejecutar los controladores allí mismo. Dado que su <input> es dentro de su <td>, el evento va a burbujear al <td> en sí mismo, donde se ejecutará justo en ese controlador de nuevo.

También tenga en cuenta que esta línea aquí:

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

no es quizá lo que quiere - Creo que siempre habrá ingrese la palabra "desactivado". Tal vez te referías

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

Estoy usando la consola Firebug, por lo que en mi caso todo funciona como se esperaba. – Marek

6

Para evitar burbujeo caso, colocar event.stopPropagation() en el controlador del evento click de su input del elemento.

$('#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: Como se ha señalado @Pointy, que puede ser su intención de tener el mismo manejador de manejar ambos eventos, o al menos tener el manejador td todavía disparar cuando haces clic en input.

Si ese es el caso, sólo tendrá que comprobar para ver si el manejador td fue despedido por un clic en el input, y si es así, evitar que el input.trigger("click") se ejecute:

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

Otra forma para hacer la prueba sería:

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

Ambos enfoques asumen que hay una sola input. Si ese no es el caso, deberá proporcionar un identificador para permitir que la prueba sea más específica.

+0

Esto es cierto, pero me pregunto si sería una buena idea. Si él realmente quiere manejar un "clic" en el nivel '', puede ser malo cancelar el burbujeo en '' porque eso desviará los clics al ''. Por supuesto, depende de qué más hay en la celda de la tabla. – Pointy

+0

@Pointy - Tienes razón. Mi suposición es que el clic para el 'td' está ocurriendo en otro lugar en' td', y como tal, el controlador estaría separado. Si ese no es el caso, OP probablemente deba probar el 'evt.target' en el manejador' td' para ver si el clic estaba en 'input', y si es así, omitir el 'click()' la 'entrada'. – user113716

+0

Buena respuesta, +1 – Mark

Cuestiones relacionadas