.clone() creates a deep copy of matched elements (and their descendants) since jQuery 1.0. The original stays in place — chain .appendTo() or similar to insert the copy.
Remember
$(".hello").clone().appendTo(".goodbye") // copy, then insert
$(".hello").appendTo(".goodbye") // moves — original leaves
.clone() // structure only (default)
.clone(true) // + events and .data() (1.4+)
.clone(true, true) // + events/data on children (1.5+)
Copy first, optionally tweak the clone, then insert it.
Select the element(s) you want to duplicate.
Call .clone() or .clone(true) / .clone(true, true) as needed.
Optionally change attributes (especially id) on the clone.
Insert with .appendTo(), .prependTo(), .insertAfter(), etc.
Piece
Required?
Role
Matched set
Yes
Element(s) to deep-copy
withDataAndEvents
Optional
Copy events + .data() (default false)
deepWithDataAndEvents
Optional
Same for descendants (1.5+; defaults to first arg)
Return
—
New jQuery set of cloned elements
Pseudocode
Pseudocode
for each matched element el:
copy = deep_copy(el and all descendants)
if withDataAndEvents:
copy events and .data() on el
// note: object/array data values stay shared
if deepWithDataAndEvents:
copy events and .data() on descendants too
add copy to result set
return result set // original DOM unchanged until you insert
Rename..attr("id", "card-2") makes the copy unique.
Insert. Append into the tray only after the id is fixed.
Tip. Prefer classes when building reusable templates.
Edge Cases & Pitfalls
Check these before relying on .clone() in production.
id
Duplicate IDs break uniqueness
Always rename cloned ids (and related for / ARIA hooks) before insert.
events
Handlers need .clone(true)
Default clones look the same but do not fire the original handlers. Pass true (and the deep flag when needed).
data
Object .data() is shared
Arrays/objects in .data() are not deep-copied. Clone them manually if originals must stay independent.
forms
Textarea / select state may be lost
Typed input values usually copy; textarea text and select choices often do not — re-apply if required.
Compatibility
Browser Support
.clone() has been part of jQuery since 1.0. Copying events/data arrived in 1.4; deepWithDataAndEvents arrived in 1.5 (default false again from 1.5.1).
✓ Stable · jQuery 1.0+
jQuery .clone()
Supported in all browsers that run jQuery 1.0+. Prefer a current jQuery 3.x build for modern projects.
100%jQuery core method
Google ChromeAll versions · Desktop & Mobile
Full support
Mozilla FirefoxAll versions · Desktop & Mobile
Full support
Apple SafariAll versions · macOS & iOS
Full support
Microsoft EdgeAll versions · Chromium & Legacy
Full support
Internet ExplorerIE 6+ · Legacy environments
Full support
OperaAll modern versions
Full support
.clone()Universal
Bottom line: Safe for any project that already loads jQuery. Use .clone(true) when handlers must travel with the copy.
Analysis
Performance Notes
Approach
Cost
Best for
.clone()
Deep DOM copy
Small/medium widgets
.clone(true, true)
Heavier
Trees with nested handlers
Build with $("<div>")
Often cheaper
Many identical rows from data
Cloning large subtrees repeatedly is expensive. For big lists, prefer a template string or a DocumentFragment instead of cloning a live node hundreds of times.
Remember
Key Takeaways
Role: deep-copy matched elements; original stays put.
Insert: chain .appendTo() / .insertAfter() on the clone.
Events: use .clone(true) (and deep flag for children).
IDs: rename clones before inserting into the document.
One line:.clone() duplicates nodes so you can insert copies without moving the original.
Frequently Asked Questions
.clone() creates a deep copy of the matched elements, including descendants and text nodes. The original stays put. Chain an insertion method such as .appendTo() or .insertAfter() to place the copy. Available since jQuery 1.0.
Appending an element already in the document moves it. Calling .clone() first copies it, so the original remains and the copy is inserted.
By default, no. Use .clone(true) to copy event handlers and (since 1.4) .data() values. As of 1.5, a second argument deepWithDataAndEvents controls whether children also get events and data.
The optional second Boolean (jQuery 1.5+) copies events and data on all descendants. By default it matches the first argument. Use .clone(true, true) for the element and its children.
Cloning copies attributes, including id. IDs must be unique. Change the clone’s id (and related for/aria hooks) before inserting, or prefer classes for elements you plan to duplicate.
For input elements, typed text and checkbox state are generally kept. For performance, user data in textarea and selections on select are not copied — re-apply those values if needed.
No. Arrays and objects inside .data() are shared between the original and the clone. Deep-copy them manually with something like $.extend([], arr) when needed.