jQuery clone () não clona ligações de eventos, mesmo com on ()

100

Eu criei uma série de eventos jQuery personalizados para uso em aplicativos da web móvel. Eles funcionam muito bem e foram testados. No entanto, encontrei um pequeno problema que não consigo entender.

Estou usando .clone()alguns elementos dentro do DOM, que contêm um botão. O botão possui alguns dos eventos personalizados vinculados a ele (os eventos são vinculados com .on()), mas. Infelizmente, quando uso o jQuery .clone(), as ligações não são preservadas e tenho que adicioná-las novamente.

Alguém já encontrou isso antes, alguém sabe de uma solução alternativa? Eu pensei que o uso .on()deveria preservar a ligação para os elementos que existem agora ou no futuro?

BenM
fonte
"Achei que usar .on () deveria preservar a vinculação para os elementos que existem agora ou no futuro?" - Isso tem pouco a ver com .clone; é a lógica de delegação de eventos do jQuery e funciona se você passar um seletor adicional para .on.
pimvdb

Respostas:

213

Acho que você deve usar esta sobrecarga do método .clone () :

$element.clone(true, true);

clone ([withDataAndEvents] [, deepWithDataAndEvents])

withDataAndEvents : um booleano que indica se os manipuladores de eventos e os dados devem ser copiados junto com os elementos. O valor padrão é falso.

deepWithDataAndEvents : um booleano que indica se os manipuladores de eventos e os dados de todos os filhos do elemento clonado devem ser copiados. Por padrão, seu valor corresponde ao valor do primeiro argumento (cujo padrão é falso).


Esteja ciente de que .on()isso não vincula realmente os eventos aos destinos, mas ao elemento ao qual você está delegando. Então, se você tem:

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

Os eventos estão realmente vinculados #container. Quando .buttonocorre um clique em um elemento, ele borbulha para o #containerelemento. O elemento que disparou o evento é avaliado no parâmetro seletor de .on()e, se corresponder, o manipulador de eventos é executado. É assim que funciona a delegação de eventos.

Se você clonar o elemento #container, terá que clonar profundamente com eventos e dados para as ligações feitas com .on()a serem preservadas.

Isso não seria necessário se você estivesse usando .on()em um dos pais de #container.

Didier Ghys
fonte
20
Nunca soube de .clone()argumentos aceitos. FML. Obrigado pela ajuda.
BenM
1
@DidierGhys Obrigado, tenho lutado para .clone()não clonar o .data()(ambos os data-xxxx="somedata"dados e no DOM) .. Isso também corrige!
Richard de Wit
Eu fiz esta pergunta , mas ninguém me respondeu. Pode me ajudar?
Ali Soltani de
Excelente, tive que fazer um clickevento para anexar a nova div clonada. readynão estava funcionando
csandreas1
4

Você deve estar ciente do fato de que a funcionalidade de clonagem profunda foi adicionada à versão 1.5 do jQuery.

Mais informações sobre este assunto:

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

Giedrius Vičkus
fonte