2012-02-28 44 views
9

Estoy teniendo algunos problemas en la ejecución del siguiente código:no selectora, en(), haga clic en evento

var i = 1; 
$('.hello:not(.selected)').on('click',function(){ 
    $(this).addClass('selected');  
    console.log(i++); 
}); 

El problema es que este código debe desencadenar una sola vez después de la clase seleccionada ha añadido, pero es ejecutándose muchas veces, solo quiero que la variable i no se incremente. En otras palabras, estoy tratando de hacer lo siguiente (que funciona, pero no quiero utilizar la función en vivo ya que se use):

$('.hello:not(.selected)').live('click', function() { 
    $('.hello').removeClass('selected'); 
    $(this).addClass('selected'); 
... 
}); 

Muchas gracias por sus respuestas de antemano, k

+0

por favor, explique en detalle un poco más lo que es la comportamiento esperado. ¿Qué quieres lograr con esto? – kapa

+0

Creo que olvidó un código adicional.Por favor explique –

+0

también existe la opción de usar [.one()] (http://api.jquery.com/one/) – rkw

Respuesta

16

Su código está tomando el conjunto de elementos que Actualmente satisfacer este criterio:

$('.hello:not(.selected)') 

y la creación de este controlador de eventos por toda la eternidad:

.on('click',function(){ 
    $(this).addClass('selected'); 
    $(this).css({opacity : 0.5});  
    console.log(i++); 
}); 

Particularmente importante es el hecho de que una vez que el controlador se establece en un elemento, continuará activo incluso si más adelante ese elemento ya no cumple con los criterios (en este caso, al obtener la clase selected).

Existen varias formas de lograr el comportamiento deseado. Una de ellas sería para comprobar dinámicamente que el "filtro" condición todavía lleva a cabo dentro del controlador de eventos:

$('.hello').on('click',function(){ 
    if($(this).hasClass('selected')) { 
     return; 
    } 
    $(this).addClass('selected'); 
    $(this).css({opacity : 0.5});  
    console.log(i++); 
}); 

Otra sería delegar el evento - en este caso, un elemento principal sería notificado del evento en uno de sus descendientes y sería dinámicamente cheque que dijo descendientes satisface la condición de filtro antes de decidir para activar el controlador de eventos (código descaradamente pegado de la respuesta de Ben Lee):

$('body').on('click', '.hello:not(.selected)', function() { 
    $(this).addClass('selected'); 
    $(this).css({opacity : 0.5});  
    console.log(i++); 
}); 
+0

Entiendo lo que quiere decir con por toda la eternidad, solo me preguntaba cómo funciona esto: $ ('. tab: not (.active)'). live ('clic', función() {, es por el live isnt it ?, pero tampoco está configurando este controlador de eventos por toda la eternidad, lo siento pero estoy un poco confundido ... pero muchas gracias ... porque funciona! – MariaZ

+0

@ThePrincessKarina: Sí, 'live' delega el evento y así termina comprobando dinámicamente. Así es como puede" asociar un controlador "a elementos que ni siquiera existen en el momento en que llamas a' live '. – Jon

+0

oooow !!! ok !, muchas gracias – MariaZ

7

El problema es que el controlador de eventos no se elimina solo porque usted cambie la clase. Estás uniendo los eventos a los elementos, y permanecen allí para siempre.

Para evitar esto, sólo pudo hacerse la prueba para la clase "seleccionado" en cada contexto de sucesos:

$('.hello:not(.selected)').on('click',function(){ 
    if ($(this).hasClass('selected')) { 
     $(this).addClass('selected'); 
     $(this).css({opacity : 0.5});  
     console.log(i++); 
    } 
}); 

Pero para la eficiencia y el código más simple, probablemente debería delegar esta:

$('body').on('click', '.hello:not(.selected)', function() { 
    var $self = $(this); 
    $self.addClass('selected'); 
    $self.css({opacity : 0.5});  
    console.log(i++); 
}); 

Utilicé "cuerpo" como el elemento para adjuntar esta delegación, pero probablemente debería usar algo más bajo en el árbol, como un padre o abuelo de los elementos ".hello". Esto solo asocia un controlador de eventos y depende del burbujeo para probar el estado seleccionado de cada elemento a medida que cambian en tiempo real.

También tenga en cuenta que caché var $self = $(this); eso también fue para la eficiencia, por lo que no terminas jQuery: extendiendo el elemento más de lo que necesitas.

+0

Muy bien, funciona ... muchas gracias por los consejos para hacer que mi código sea más eficiente . Con mi código, estaba tratando de replicar el "$ ('. Tab: not (.active)'). Live ('click', function() {", pero usando el "on", creo que no lo restauro y muy bien el encendido, pero esto aclare ... ¡Gracias! – MariaZ

Cuestiones relacionadas