jQuery / Método / .clone() - Copiar elementos selecionados
No jQuery, .clone() cria um novo objeto jQuery com cópias dos elementos selecionados, seus descendentes e texto. Clonar não os inclui na página: insira com .appendTo(), por exemplo. Eventos e dados jQuery são excluídos por padrão e controlados por argumentos separados.
Estrutura, movimentação e opções de eventos
Na documentação de .clone(), uma cópia estrutural profunda inclui os filhos. Não garante independência completa de eventos, objetos .data() e valores aninhados. O segundo argumento deepWithDataAndEvents controla eventos/dados dos descendentes, não a cópia dos filhos DOM.
| Expressão | Elemento e descendentes | Eventos/dados da raiz | Eventos/dados dos descendentes |
|---|---|---|---|
| .clone() | Copiados | Não copiados | Não copiados |
| .clone(true, false) | Copiados | Copiados | Não copiados |
| .clone(true, true) | Copiados | Copiados | Copiados |
| .clone(true) | Copiados | Copiados | Copiados; o segundo argumento segue o primeiro |
Inserir um elemento existente em um único destino com .appendTo() o move. Para manter o original, clone antes. São elementos separados do modelo de objetos do documento, DOM; mudar o título da cópia não muda o original.
Exemplo completo de dados e cliques em cartões
Salve todo o código em UTF-8 como clone-demo.html e abra no navegador. jQuery 4.0.0 vem da rede oficial de distribuição de conteúdo, CDN; exige internet, sem instalação. Os três modos, cliques, dados compartilhados e Reset foram executados com 3.7.1 e 4.0.0.
A raiz original guarda count e kind; o botão interno Increment tem manipulador direto. O código zera explicitamente o contador e o número exibido de cada cópia. Clonar não reinicia contadores automaticamente.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Clone structure, data and events</title>
<style>
body { font: 16px/1.6 sans-serif; margin: 24px; }
.card { padding: 14px; margin: 12px 0; border: 1px solid #8aa; }
.card p { margin: 4px 0; }
button { margin: 4px; padding: 8px; }
</style>
<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
</head>
<body>
<h1>Clone structure, data and events</h1>
<div class="card" id="source">
<p class="label">Original</p>
<p>Count: <span class="count">0</span></p>
<p>Data: <span class="data">stored</span></p>
<button type="button" class="increment">Increment</button>
</div>
<button type="button" id="plain">Clone structure</button>
<button type="button" id="parent">Clone parent data</button>
<button type="button" id="full">Clone events</button>
<button type="button" id="reset">Reset</button>
<div id="copies"></div>
<p id="result" aria-live="polite"></p>
<script>
$(function () {
const $source = $("#source").data({ count: 0, kind: "stored" });
let serial = 1;
function report() {
$("#result").text(`source=${$source.data("count")} | copies=${$("#copies > .card").length}`);
}
$source.find(".increment").on("click", function () {
const $card = $(this).closest(".card");
const count = $card.data("count") + 1;
$card.data("count", count).find(".count").text(count);
report();
});
function copy(withData, deep) {
const $copy = $source.clone(withData, deep);
$copy.attr("id", "copy-" + serial);
$copy.find(".label").text("Copy " + serial++);
$copy.data("count", 0).find(".count").text(0);
$copy.find(".data").text($copy.data("kind") || "none");
$copy.appendTo("#copies");
report();
}
$("#plain").on("click", () => copy(false, false));
$("#parent").on("click", () => copy(true, false));
$("#full").on("click", () => copy(true, true));
$("#reset").on("click", function () {
$("#copies").empty();
serial = 1;
$source.data("count", 0).find(".count").text(0);
report();
});
report();
});
</script>
</body>
</html>
Inicialmente, só existe o original:
source=0 | copies=0
- Use Increment do original uma vez para obter Count 1.
- Clone structure copia estrutura sem kind nem manipulador. Copy 1 mostra Data none e seu botão mantém zero.
- Clone parent data copia kind e mostra stored, mas não o manipulador do botão descendente; não incrementa.
- Clone events inclui manipuladores descendentes. Copy 3 passa a 1 e o original permanece 1.
- Reset remove as cópias e reinicia contador original e numeração. Não registra novamente o manipulador original; cada clique continua incrementando uma vez após repetir Reset.
Antes de inserir, a raiz recebe ID único como copy-1; partes internas usam classes. Se descendentes têm IDs ou referências label for e aria-controls, atualize identificadores e referências juntos.
Copiar objetos e arrays aninhados explicitamente
Objetos e arrays em .data() copiados por .clone(true) podem permanecer compartilhados. Execute este trecho completo no console de desenvolvimento; ele usa elementos temporários sem inserção.
const $original = $("<div>").data("options", { tags: ["a"] });
const $shared = $original.clone(true);
$shared.data("options").tags.push("b");
console.log($original.data("options").tags.join(", "));
const $independent = $original.clone(true).data("options", {
tags: [...$original.data("options").tags]
});
$independent.data("options").tags.push("c");
console.log($original.data("options").tags.join(", "));
console.log($independent.data("options").tags.join(", "));
a, b
a, b
a, b, c
Acrescentar b pela primeira cópia também muda o original para a, b porque ambos usam o mesmo options. A cópia independente recebe options e tags novos; incluir c deixa o original em a, b. Copia-se uma estrutura conhecida com array de strings, não qualquer objeto profundamente aninhado.
Estado de formulários, eventos e problemas
Não suponha que todo controle copia igualmente seu estado atual. A documentação distingue input de textarea/select. Confira os valores necessários e considere definir seleções e notas explicitamente com .val() após clonar.
Copiar todos os manipuladores não é a única opção para novos cartões. A delegação com .on() em um pai persistente pode tratar descendentes novos. Combinar manipuladores diretos copiados e delegação pode duplicar ações; escolha e confira a abordagem necessária.
Se a cópia não aparecer, examine inserção e destino. Para botões inativos, confira se o manipulador estava na raiz ou nos descendentes e os dois argumentos. Conjunto vazio produz cópia vazia; IDs duplicados podem desviar seletores e rótulos. Examine também Network e Console.




