The JavaScript cloneNode() method creates a copy of a DOM node. You can use it to duplicate an element, its attributes, and—when requested—its child nodes. It is useful when building dynamic interfaces, repeating list items, creating reusable UI structures, and inserting copies of existing HTML elements.
What Is the cloneNode() Method in JavaScript?
cloneNode() is a DOM Node method that returns a duplicate of the node on which it is called. It does not automatically insert the new node into the document. To display the copy, append or insert it into a parent element.
The method supports two modes:
- Shallow clone: copies the node itself and its attributes, but not its child nodes.
- Deep clone: copies the node and its complete subtree, including descendant elements and text nodes.
Syntax of cloneNode()
const clonedNode = originalNode.cloneNode(deep);
| Parameter | Description |
|---|---|
deep (optional) |
A Boolean value. Use true to clone the node and all descendants. Use false or omit it to clone only the node itself. |
Return value: A new Node object that is a copy of the original node.
JavaScript cloneNode() Example
In this example, an existing paragraph is cloned and the copy is added to the same container.
<div id="container">
<p id="message">Learn JavaScript DOM methods.</p>
</div>
<script>
const original = document.getElementById("message");
const copy = original.cloneNode();
document.getElementById("container").appendChild(copy);
</script>
Because the argument is omitted, this is a shallow clone. The paragraph’s text is a child text node, so the cloned paragraph has no text content. To copy the text as well, use cloneNode(true).
Shallow Cloning with cloneNode(false)
A shallow clone copies only the selected node and its attributes. It does not copy nested elements or text nodes.
<div id="source" class="panel" data-type="info">
<h3>JavaScript Tutorial</h3>
<p>Learn DOM manipulation.</p>
</div>
<script>
const source = document.getElementById("source");
const shallowCopy = source.cloneNode(false);
document.body.appendChild(shallowCopy);
console.log(shallowCopy.className); // panel
console.log(shallowCopy.children.length); // 0
console.log(shallowCopy.textContent); // ""
</script>
The new div keeps its attributes, such as class and data-type, but its heading and paragraph are not copied.
Deep Cloning with cloneNode(true)
Pass true to copy the node together with all of its descendants. This includes nested elements and text nodes.
<div id="source" class="card">
<h2>DOM Tutorial</h2>
<p>Explore JavaScript DOM methods.</p>
<ul>
<li>Select elements</li>
<li>Update content</li>
</ul>
</div>
<script>
const source = document.getElementById("source");
const deepCopy = source.cloneNode(true);
document.body.appendChild(deepCopy);
</script>
The cloned card contains the heading, paragraph, list, list items, and their text. The original node remains unchanged.
Clone an HTML Element and Change Its Content
You can modify a cloned element before adding it to the page. This is helpful when creating repeated interface items.
<div id="product" class="product">
<h3 class="name">Product One</h3>
<p class="price">$20</p>
</div>
<div id="products"></div>
<script>
const template = document.getElementById("product");
const products = document.getElementById("products");
const newProduct = template.cloneNode(true);
newProduct.querySelector(".name").textContent = "Product Two";
newProduct.querySelector(".price").textContent = "$35";
products.appendChild(newProduct);
</script>
The example creates a copy, changes its text, and appends it to the products container. In production code, consider using a template element for reusable markup.
Clone Multiple Elements in a Loop
You can call cloneNode(true) repeatedly to create several copies from one source element.
<div id="source-item">
<span>Sample item</span>
</div>
<ul id="item-list"></ul>
<script>
const sourceItem = document.getElementById("source-item");
const itemList = document.getElementById("item-list");
for (let i = 1; i <= 3; i++) {
const copy = sourceItem.cloneNode(true);
copy.querySelector("span").textContent = "Item " + i;
itemList.appendChild(copy);
}
</script>
Each iteration creates a separate copy. You can update the copy independently before inserting it.
Does cloneNode() Copy Event Listeners?
No. The cloneNode() method copies the node’s structure and attributes, but it does not copy event listeners registered with addEventListener(). It also does not copy event handler properties assigned directly through JavaScript.
const button = document.getElementById("myButton");
button.addEventListener("click", function () {
console.log("Original button clicked");
});
const buttonCopy = button.cloneNode(true);
document.body.appendChild(buttonCopy);
// The copied button does not have the listener above.
Attach a listener to the cloned element if it needs its own behavior:
buttonCopy.addEventListener("click", function () {
console.log("Copied button clicked");
});
Alternatively, use event delegation on a shared parent when many dynamically created elements need the same interaction.
cloneNode() vs. appendChild()
These methods have different purposes:
| Method | Purpose |
|---|---|
cloneNode() |
Creates and returns a copy of a node. It does not insert the copy into the document. |
appendChild() |
Inserts a node at the end of a parent element’s child list. If the node already exists elsewhere, it moves it rather than copying it. |
To duplicate and insert an element, use both methods:
const original = document.querySelector(".item");
const copy = original.cloneNode(true);
document.querySelector(".list").appendChild(copy);
Important Things to Remember When Using cloneNode()
- Duplicate IDs: Cloning an element with an
idcopies that ID. If both elements are placed in the same document, update the cloned ID to keep IDs unique. - Event listeners: Listeners registered with
addEventListener()are not copied. Add them to the clone or use event delegation. - Canvas content: A canvas element’s painted bitmap is not copied by
cloneNode(); copy its drawing content separately when needed. - Form controls: Some live user-edited state may not behave exactly like the original in every case. Set the desired value or checked state explicitly when creating form-control copies.
- Document insertion: The returned node is detached until you insert it using a method such as
appendChild(),append(), orinsertBefore().
Browser Support
The cloneNode() method is a long-established DOM API and is supported by all modern browsers, including Chrome, Firefox, Safari, and Edge. It is suitable for everyday DOM manipulation without an additional library.
