2010-05-25 19 views
12

Tengo dos divs, uno que contiene algunas cosas y el otro con todas las cosas posibles. Al hacer clic en uno de los divs se transferirán ítems al otro div. El código que se me ocurrió es:jQuery: ¿Hay alguna manera de "actualizar" los manejadores de eventos?

$("#holder > *").each(function() { 
    $(this).click(function(e) { 
     $(this).remove(); 
     $("#bucket").append(this); 
    }); 
}); 

$("#bucket > *").each(function() { 
    $(this).click(function(e) { 
     $(this).remove(); 
     $("#holder").append(this); 
     }); 
}); 

Esta funciona perfectamente, excepto que los controladores de eventos deben ser refrescado una vez añado o elimino elementos. Lo que quiero decir es que, si primero hago clic en un elemento, se agrega al otro div, pero si vuelvo a hacer clic en este elemento, no pasa nada. Puedo hacerlo manualmente, pero ¿hay una mejor manera de lograr esto?

Respuesta

20

Pruebe jquery live events .. $ .live (nombre de evento, función) se vinculará a cualquier elemento actual que coincida con los elementos añadidos a la Dom en el futuro mediante la manipulación de javascript.

ejemplo:

$("#holder > *").live("click", function(e) { 
     $(this).remove(); 
     $("#bucket").append(this); 
}); 

$("#bucket > *").live("click", function(e) { 
     $(this).remove(); 
     $("#holder").append(this); 
}); 

Importante:

Tenga en cuenta que $.live ya ha sido despojado de jQuery (1.9 en adelante) y que en su lugar debe usar $.on.

Le sugiero que consulte this answer para obtener un ejemplo actualizado.

+0

@John: Gracias por la respuesta. No estoy seguro de si me falta pero cuando reemplazo mi código con esto, no pasa nada. Estoy usando jQuery-1.4.2.¿Me estoy perdiendo algo? Quiero decir, incluso los eventos iniciales no funcionan. – Legend

+1

Esto no funcionará. 'jQuery.fn.live' necesita un selector para trabajar ... no puede funcionar con' $ (this) '... – James

+0

Supongo que sí. Sabía que "esto" está estropeando las cosas. – Legend

1

¿Ha mirado la función live de jQuery?

+0

Gracias por los consejos. Actualmente mirándolo. – Legend

+1

'live' ha quedado en desuso – craned

2

EDITAR: no utilizar en vivo, se desaprobará!

Aproveche el hecho de que los eventos burbujean. Usando .on():

var = function(el1, el2) { 

var things = $('#holder, #bucket'); 
things.each(function(index) { 
    // for every click on or in this element 
    things.eq(index).on('click', '> *', function() { 
    // append will remove the element 
    // Number(!0) => 1, Number(!1) => 0 
    things.eq(Number(!index)).append(this); 
    }); 
}); 

cualquier clic en cualquier elemento (existente en el momento de aprieto o no) se burbujear (suponiendo que no haya capturado manualmente el evento y dejado de propagación). Por lo tanto, puede usar ese event delegation para vincular solo dos eventos, uno en cada contenedor. Cada clic que pasó la prueba de selección del segundo argumento (en este caso, > *, eliminará que elemento y luego añadirlo al contenedor alternativo como accesesed por things.eq(Number(!index))

+0

En realidad, no lo hará. A menos que quieras desvincular/enlazar cuando los elementos se agreguen al DOM. Creo que quieres decir .live ('click', function() { –

+0

Según entendí, el enlace no funciona con elementos futuros, sino solo con elementos que actualmente coinciden con un selector determinado [quote from 'live' documentation in jQuery) : "Este elemento nuevo también coincide con el selector .clickme, pero dado que se agregó después de la llamada a .bind(), los clics en él no harán nada". –

+0

Me refería a .live, sry para la confusión - estaba recogiendo a mi novia y estaba apurado escribiéndolo en mi teléfono y escribí un enlace fuera de habbit, lol –

6

Aquí tiene, utilizando la más intuitiva delegate API: ..

var holder = $('#holder'), 
    bucket = $('#bucket'); 

holder.delegate('*', 'click', function(e) { 
    $(this).remove(); 
    bucket.append(this); 
}); 

bucket.delegate('*', 'click', function(e) { 
    $(this).remove(); 
    holder.append(this); 
}); 
+0

@ J-P: Ahh ... Acabo de aceptar la solución de John. +1 por la ayuda. Solo como curiosidad, ¿hay alguna ventaja al usar delegate en vivo? – Legend

+0

@Legend, sí, es más rápido, porque no requiere que seleccione '' #header> * 'y' #bucket> * 'en forma redundante primero. – James

+0

@ J-P: tiene sentido. Gracias por la explicación. – Legend

1

en primer lugar, es obsoleto live en segundo lugar, la actualización no es lo que quiere Sólo tiene que conectar el controlador de clic a la fuente de derecho, en este caso: el documento

Wh. es usted

$(document).on('click', <id or class of element>, <function>); 

el controlador de clic se adjunta al documento. Cuando se carga la página, el controlador de clic se adjunta a una instancia específica de un elemento. Cuando la página se vuelve a cargar, esa instancia específica se ha ido para que el controlador no registre ningún clic. Pero la página permanece así que conecte el manejador de clic al documento. Simple y fácil.

Cuestiones relacionadas