jQuery clone () no clonando enlaces de eventos, incluso con on ()

100

He creado una serie de eventos personalizados de jQuery para usar en aplicaciones web móviles. Funcionan muy bien y han sido probados. Sin embargo, me he encontrado con un pequeño problema que me cuesta entender.

Estoy usando .clone()algunos elementos dentro del DOM, que contienen un botón. El botón tiene algunos de los eventos personalizados vinculados a él (los eventos están vinculados mediante .on()), pero. Desafortunadamente, cuando uso jQuery's .clone(), los enlaces no se conservan y tengo que agregarlos nuevamente.

¿Alguien se ha encontrado con esto antes, alguien sabe de un posible trabajo alrededor? Pensé que .on()se suponía que el uso preservaba el enlace de los elementos que existen ahora o en el futuro.

BenM
fuente
"Pensé que el uso de .on () se suponía que debía preservar el enlace de los elementos que existen ahora o en el futuro". - Esto tiene poco que ver con .clone; es la lógica de delegación de eventos de jQuery y funciona si pasa un selector adicional a .on.
pimvdb

Respuestas:

213

Creo que deberías usar esta sobrecarga del método .clone () :

$element.clone(true, true);

clon ([withDataAndEvents] [, deepWithDataAndEvents])

withDataAndEvents : un valor booleano que indica si los controladores de eventos y los datos deben copiarse junto con los elementos. El valor predeterminado es falso.

deepWithDataAndEvents : un valor booleano que indica si se deben copiar los controladores de eventos y los datos de todos los elementos secundarios del elemento clonado. Por defecto, su valor coincide con el valor del primer argumento (que por defecto es falso).


Tenga en cuenta que en .on()realidad no vincula los eventos a los objetivos, sino al elemento en el que está delegando. Entonces, si tienes:

$('#container').on('click', '.button', ...);

Los eventos están realmente ligados a #container. Cuando se .buttonproduce un clic en un elemento, aparece el #containerelemento. El elemento que desencadenó el evento se evalúa en el parámetro selector de .on()y, si coincide, se ejecuta el controlador de eventos. Así es como funciona la delegación de eventos.

Si clona el elemento #container, debe realizar una clonación profunda con eventos y datos para .on()que se conserven los enlaces realizados .

Esto no sería necesario si estuviera usando .on()en un padre de #container.

Didier Ghys
fuente
20
Nunca conocí .clone()argumentos aceptados. FML. Gracias por tu ayuda.
BenM
1
@DidierGhys Gracias, he estado luchando por .clone()no clonar .data()(ambos data-xxxx="somedata"y los datos en el DOM). ¡Esto también lo soluciona!
Richard de Wit
Hice esta pregunta , pero nadie me respondió. ¿Me puedes ayudar?
Ali Soltani
Excelente, tuve que hacer un clickevento para agregar el nuevo div clonado. readyno estaba funcionando
csandreas1
4

Debe tener en cuenta el hecho de que se agregó la funcionalidad de clonación profunda a la versión 1.5 de jQuery.

Más información sobre este tema:

http://api.jquery.com/clone/

Giedrius Vičkus
fuente