jQuery clone () nie klonuje powiązań zdarzeń, nawet z on ()

100

Stworzyłem serię niestandardowych zdarzeń jQuery do wykorzystania w mobilnych aplikacjach internetowych. Działają świetnie i zostały przetestowane. Jednak napotkałem mały problem, którego nie rozumiem.

Używam .clone()kilku elementów w DOM, które zawierają przycisk. Z przyciskiem są powiązane niektóre zdarzenia niestandardowe (zdarzenia są powiązane za pomocą .on()), ale. Niestety, kiedy używam jQuery .clone(), wiązania nie są zachowywane i muszę je dodać ponownie.

Czy ktoś spotkał się z tym wcześniej, czy ktoś wie o potencjalnym obejściu? Myślałem, że używanie .on()ma na celu zachowanie wiązania elementów, które istnieją teraz lub w przyszłości?

BenM
źródło
„Myślałem, że użycie .on () powinno zachować powiązanie elementów, które istnieją teraz lub w przyszłości?” - To ma niewiele wspólnego z .clone; jest to logika delegowania zdarzeń jQuery i działa, jeśli przekażesz dodatkowy selektor do .on.
pimvdb

Odpowiedzi:

213

Myślę, że powinieneś użyć tego przeciążenia metody .clone () :

$element.clone(true, true);

clone ([withDataAndEvents] [, deepWithDataAndEvents])

withDataAndEvents : wartość logiczna wskazująca, czy procedury obsługi zdarzeń i dane powinny być kopiowane wraz z elementami. Wartość domyślna to false.

deepWithDataAndEvents : wartość logiczna wskazująca, czy programy obsługi zdarzeń i dane dla wszystkich elementów podrzędnych sklonowanego elementu powinny zostać skopiowane. Domyślnie jego wartość jest zgodna z wartością pierwszego argumentu (domyślnie false).


Uważaj, .on()ponieważ w rzeczywistości nie wiąże zdarzeń z celami, ale z elementem, do którego delegujesz. Więc jeśli masz:

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

Zdarzenia są w rzeczywistości powiązane #container. Kliknięcie .buttonelementu powoduje przejście do #containerelementu. Element, który wyzwolił zdarzenie, jest oceniany na podstawie parametru selektora .on()i jeśli pasuje, wykonywana jest procedura obsługi zdarzenia. Tak działa delegowanie zdarzeń.

Jeśli sklonujesz element #container, musisz sklonować głęboko zdarzenia i dane, .on()aby zachować powiązania utworzone za pomocą .

Nie byłoby to konieczne, gdybyś używał .on()na rodzicu domeny #container.

Didier Ghys
źródło
20
Nigdy nie znał .clone()akceptowanych argumentów. FML. Dzięki za pomoc.
BenM
1
@DidierGhys Dzięki, zmagałem się z .clone()nie klonowaniem .data()(obu data-xxxx="somedata"i danych w DOM) .. To też rozwiązuje problem!
Richard de Wit
Zadałem to pytanie , ale nikt mi nie odpowiedział. Możesz mi pomóc?
Ali Soltani
Doskonale, musiałem utworzyć clickwydarzenie, aby dołączyć nowy sklonowany element div. readynie działał
csandreas1
4

Należy mieć świadomość, że do wersji 1.5 jQuery dodano funkcję głębokiego klonowania.

Więcej informacji na ten temat:

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

Giedrius Vičkus
źródło